package tests; import static org.junit.Assert.*; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.junit.Test; import algorithms.*; import code.ast.Annotation; import code.ast.CompilationUnit; import code.ast.FieldDeclaration; import code.ast.MethodDeclaration; import code.ast.TypeDeclaration; import code.ast.VariableDeclaration; import generators.CodeGeneratorFromDataFlowGraph; import generators.DataTransferMethodAnalyzer; import generators.JavaCodeGenerator; import generators.JavaMethodBodyGenerator; import generators.JavaSpecific; import generators.JerseyCodeGenerator; import generators.JerseyMethodBodyGenerator; import generators.JerseySpecific; import models.Edge; import models.dataFlowModel.*; import parser.*; import parser.exceptions.ExpectedAssignment; import parser.exceptions.ExpectedChannel; import parser.exceptions.ExpectedChannelName; import parser.exceptions.ExpectedColon; import parser.exceptions.ExpectedDoubleQuotation; import parser.exceptions.ExpectedEquals; import parser.exceptions.ExpectedInOrOutOrRefOrSubKeyword; import parser.exceptions.ExpectedLeftCurlyBracket; import parser.exceptions.ExpectedRHSExpression; import parser.exceptions.ExpectedRightBracket; import parser.exceptions.ExpectedRightCurlyBracket; import parser.exceptions.ExpectedStateTransition; import parser.exceptions.WrongJsonExpression; import parser.exceptions.WrongLHSExpression; import parser.exceptions.WrongPathExpression; import parser.exceptions.WrongRHSExpression; public class JAXRSCodeGeneratorTest { @Test public void test() { testAccounts(); testClock(); testCustomerManagement(); testGroupChat(); testInventoryManagement(); testOnlineBattleGame(); testOnlineBattleGame2(); testPOS(); testSimpleTwitter(); testVotingSystem(); testWeatherObservationSystem(); } private void testAccounts() { try { ArrayList<CompilationUnit> generatedCode = generateCode("models/Accounts.model", null); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Accounts", Map.entry(Set.of("@Path(\"/accounts\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "List<Account>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("List<Account>", Map.entry(List.of(), 1)))), Map.entry("getAccount", Map.entry(Set.of(), Map.entry("Account", Map.entry(List.of("int"), 1)))), Map.entry("getNameValue", Map.entry(Set.of("@Path(\"/{uid}/name\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("int"), 1)))), Map.entry("getAccountValue", Map.entry(Set.of("@Path(\"/{uid}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("int"), 1)))), Map.entry("changeName", Map.entry(Set.of("@Path(\"/{uid}/name\")","@PUT"), Map.entry("void", Map.entry(List.of("int","String"), 1)))), Map.entry("signup", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String"), 1)))))))); exprectedStructure.put("Account", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("name", "String")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getName", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 1)))), Map.entry("changeName", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int","String"), 1)))), Map.entry("Account", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testClock() { try { // check PULL-first ArrayList<CompilationUnit> generatedCode = generateCode("models/Clock.model", PushPullValue.PULL); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Hour", Map.entry(Set.of("@Path(\"/hour\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "int")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("updateFromMin", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("int"), 1)))), Map.entry("Hour", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int"), 1)))))))); exprectedStructure.put("Min_ang", Map.entry(Set.of("@Path(\"/min_ang\")","@Component"), Map.entry(Map.ofEntries(Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 2)))))))); exprectedStructure.put("Hour_ang", Map.entry(Set.of("@Path(\"/hour_ang\")","@Component"), Map.entry(Map.ofEntries(Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 2)))))))); exprectedStructure.put("Min", Map.entry(Set.of("@Path(\"/min\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "int"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("Min", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int"), 1)))), Map.entry("tick", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of(), 3)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); // check PUSH-first generatedCode = generateCode("models/Clock.model", PushPullValue.PUSH); exprectedStructure.clear(); exprectedStructure.put("Min_ang", Map.entry(Set.of("@Path(\"/min_ang\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "double")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 1)))), Map.entry("updateFromMin", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("int"), 1)))), Map.entry("Min_ang", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("double"), 1)))))))); exprectedStructure.put("Hour_ang", Map.entry(Set.of("@Path(\"/hour_ang\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "double")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 1)))), Map.entry("updateFromHour", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("int"), 1)))), Map.entry("Hour_ang", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("double"), 1)))))))); exprectedStructure.put("Min", Map.entry(Set.of("@Path(\"/min\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "int"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("Min", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int"), 1)))), Map.entry("tick", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of(), 5)))))))); exprectedStructure.put("Hour", Map.entry(Set.of("@Path(\"/hour\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "int"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("updateFromMin", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("int"), 3)))), Map.entry("Hour", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testCustomerManagement() { try { ArrayList<CompilationUnit> generatedCode = generateCode("models/CustomerManagement.model", null); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Companies", Map.entry(Set.of("@Path(\"/companies\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Company>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Company>", Map.entry(List.of(), 1)))), Map.entry("getCompany", Map.entry(Set.of(), Map.entry("Company", Map.entry(List.of("String"), 1)))), Map.entry("getAddressValue", Map.entry(Set.of("@Path(\"/{cid}/address\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("getCompanyValue", Map.entry(Set.of("@Path(\"/{cid}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("setAddress", Map.entry(Set.of("@Path(\"/{cid}/address\")","@PUT"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("addCampany", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))))))); exprectedStructure.put("Customers", Map.entry(Set.of("@Path(\"/customers\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Customer>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Customer>", Map.entry(List.of(), 1)))), Map.entry("getCustomer", Map.entry(Set.of(), Map.entry("Customer", Map.entry(List.of("String"), 1)))), Map.entry("getAddressValue", Map.entry(Set.of("@Path(\"/{uid}/address\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("getCustomerValue", Map.entry(Set.of("@Path(\"/{uid}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("getOrganizationValue", Map.entry(Set.of("@Path(\"/{uid}/organization\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("addCustomer", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("setOrganization", Map.entry(Set.of("@Path(\"/{uid}/organization\")","@PUT"), Map.entry("void", Map.entry(List.of("String","String"), 1)))))))); exprectedStructure.put("Customer", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("organization", "String"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getOrganization", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 1)))), Map.entry("getAddress", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 2)))), Map.entry("setOrganization", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("Customer", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String"), 1)))))))); exprectedStructure.put("Company", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("address", "String")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getAddress", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 1)))), Map.entry("setAddress", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("Company", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testGroupChat() { try { ArrayList<CompilationUnit> generatedCode = generateCode("models/GroupChat.model", null); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Groups", Map.entry(Set.of("@Path(\"/groups\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Group>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Group>", Map.entry(List.of(), 1)))), Map.entry("getGroup", Map.entry(Set.of(), Map.entry("Group", Map.entry(List.of("String"), 1)))), Map.entry("getMembersValue", Map.entry(Set.of("@Path(\"/{gid}/members\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("List<String>", Map.entry(List.of("String"), 1)))), Map.entry("getMessagesValue", Map.entry(Set.of("@Path(\"/{gid}/messages\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("List<String>", Map.entry(List.of("String"), 1)))), Map.entry("getGroupValue", Map.entry(Set.of("@Path(\"/{gid}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("addGroupMember", Map.entry(Set.of("@Path(\"/{gid}/members\")","@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("postMessage", Map.entry(Set.of("@Path(\"/{gid}/messages\")","@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("createGroup", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String"), 1)))))))); exprectedStructure.put("Account", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("notifications", "Map<String, Boolean>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getNotifications", Map.entry(Set.of(), Map.entry("Map<String, Boolean>", Map.entry(List.of(), 1)))), Map.entry("updateNotificationsFromMessages", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String","int","List<String>","String"), 1)))), Map.entry("hasRead", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("Account", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("Map<String, Boolean>"), 1)))))))); exprectedStructure.put("Group", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("messages", "List<String>"), Map.entry("client", "Client"), Map.entry("members", "List<String>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getMessages", Map.entry(Set.of(), Map.entry("List<String>", Map.entry(List.of(), 1)))), Map.entry("getMembers", Map.entry(Set.of(), Map.entry("List<String>", Map.entry(List.of(), 1)))), Map.entry("postMessage", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 6)))), Map.entry("addGroupMember", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("Group", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("List<String>","List<String>"), 2)))))))); exprectedStructure.put("Accounts", Map.entry(Set.of("@Path(\"/accounts\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Account>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Account>", Map.entry(List.of(), 1)))), Map.entry("getAccount", Map.entry(Set.of(), Map.entry("Account", Map.entry(List.of("String"), 1)))), Map.entry("updateNotificationsFromMessages", Map.entry(Set.of("@Path(\"accounts/{v1}/notifications\")","@POST"), Map.entry("void", Map.entry(List.of("String","String","int","List<String>","String"), 1)))), Map.entry("getNotificationsValue", Map.entry(Set.of("@Path(\"/{v1}/notifications\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Boolean>", Map.entry(List.of("String"), 1)))), Map.entry("getAccountValue", Map.entry(Set.of("@Path(\"/{v1}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("hasRead", Map.entry(Set.of("@Path(\"/{aid}/notifications\")","@DELETE"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("signUp", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testInventoryManagement() { try { ArrayList<CompilationUnit> generatedCode = generateCode("models/InventoryManagement.model", null); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("InventoryElement", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("count", "int")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getCount", Map.entry(Set.of(), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("receiveOrShip", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","int"), 1)))), Map.entry("InventoryElement", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int"), 1)))))))); exprectedStructure.put("Inventory", Map.entry(Set.of("@Path(\"/inventory\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, InventoryElement>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, InventoryElement>", Map.entry(List.of(), 1)))), Map.entry("getInventoryElement", Map.entry(Set.of(), Map.entry("InventoryElement", Map.entry(List.of("String"), 1)))), Map.entry("getInventoryElementValue", Map.entry(Set.of("@Path(\"/{itemId}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("getCountValue", Map.entry(Set.of("@Path(\"/{itemId}/count\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of("String"), 1)))), Map.entry("registerItem", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String","int","String"), 1)))), Map.entry("receiveOrShip", Map.entry(Set.of("@Path(\"/{itemId}/count\")","@POST"), Map.entry("void", Map.entry(List.of("String","int"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testOnlineBattleGame() { try { // check PULL-first ArrayList<CompilationUnit> generatedCode = generateCode("models/OnlineBattleGame.model", null); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Rooms", Map.entry(Set.of("@Path(\"/rooms\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Room>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Room>", Map.entry(List.of(), 1)))), Map.entry("getRoom", Map.entry(Set.of(), Map.entry("Room", Map.entry(List.of("String"), 1)))), Map.entry("getBlue_idValue", Map.entry(Set.of("@Path(\"/{rid}/blue_id\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("getRed_nameValue", Map.entry(Set.of("@Path(\"/{rid}/red_name\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("getBlue_nameValue", Map.entry(Set.of("@Path(\"/{rid}/blue_name\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("getRed_idValue", Map.entry(Set.of("@Path(\"/{rid}/red_id\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("getRoomValue", Map.entry(Set.of("@Path(\"/{rid}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("changeBlueId", Map.entry(Set.of("@Path(\"/{rid}/blue_id\")","@PUT"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("createRoom", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String","String","String"), 1)))), Map.entry("changeRedId", Map.entry(Set.of("@Path(\"/{rid}/red_id\")","@PUT"), Map.entry("void", Map.entry(List.of("String","String"), 1)))))))); exprectedStructure.put("Room", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("blue_id", "String"), Map.entry("red_id", "String"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getBlue_id", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 1)))), Map.entry("getRed_id", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 1)))), Map.entry("getRed_name", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 2)))), Map.entry("getBlue_name", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 2)))), Map.entry("changeRedId", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("changeBlueId", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("Room", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 2)))))))); exprectedStructure.put("Account", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("name", "String")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getName", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 1)))), Map.entry("changeName", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("Account", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String"), 1)))))))); exprectedStructure.put("Accounts", Map.entry(Set.of("@Path(\"/accounts\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Account>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Account>", Map.entry(List.of(), 1)))), Map.entry("getAccount", Map.entry(Set.of(), Map.entry("Account", Map.entry(List.of("String"), 1)))), Map.entry("getAccountValue", Map.entry(Set.of("@Path(\"/{aid}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("getNameValue", Map.entry(Set.of("@Path(\"/{aid}/name\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("signUp", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("changeName", Map.entry(Set.of("@Path(\"/{aid}/name\")","@PUT"), Map.entry("void", Map.entry(List.of("String","String"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testOnlineBattleGame2() { try { // check PULL-first ArrayList<CompilationUnit> generatedCode = generateCode("models/OnlineBattleGame2.model", null); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Rooms", Map.entry(Set.of("@Path(\"/rooms\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Room>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Room>", Map.entry(List.of(), 1)))), Map.entry("getRoom", Map.entry(Set.of(), Map.entry("Room", Map.entry(List.of("String"), 1)))), Map.entry("getIdValue", Map.entry(Set.of("@Path(\"/{rid}/members/{mno}/id\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String","int"), 1)))), Map.entry("getBattleValue", Map.entry(Set.of("@Path(\"/{rid}/battle\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("boolean", Map.entry(List.of("String"), 1)))), Map.entry("getRoomValue", Map.entry(Set.of("@Path(\"/{rid}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("getMemberValue", Map.entry(Set.of("@Path(\"/{rid}/members/{mno}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String","int"), 1)))), Map.entry("getMembersValue", Map.entry(Set.of("@Path(\"/{rid}/members\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("List<Member>", Map.entry(List.of("String"), 1)))), Map.entry("getNameValue", Map.entry(Set.of("@Path(\"/{rid}/members/{mno}/name\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String","int"), 1)))), Map.entry("battle", Map.entry(Set.of("@Path(\"/{rid}/battle\")","@PUT"), Map.entry("void", Map.entry(List.of("String","boolean"), 1)))), Map.entry("addRoomMember", Map.entry(Set.of("@Path(\"/{rid}/members\")","@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("createRoom", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String"), 1)))))))); exprectedStructure.put("Member", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("id", "String"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getId", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 1)))), Map.entry("getName", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 2)))), Map.entry("Member", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String"), 1)))))))); exprectedStructure.put("Account", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("name", "String"), Map.entry("point", "int")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getName", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 1)))), Map.entry("getPoint", Map.entry(Set.of(), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("updatePointFromBattle", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String","int","boolean","String"), 1)))), Map.entry("changeName", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("Account", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","int"), 2)))))))); exprectedStructure.put("Room", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("members", "Members"), Map.entry("battle", "boolean"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getMembers", Map.entry(Set.of(), Map.entry("Members", Map.entry(List.of(), 1)))), Map.entry("getBattle", Map.entry(Set.of(), Map.entry("boolean", Map.entry(List.of(), 1)))), Map.entry("battle", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","boolean"), 6)))), Map.entry("Room", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("boolean"), 1)))))))); exprectedStructure.put("Accounts", Map.entry(Set.of("@Path(\"/accounts\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Account>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Account>", Map.entry(List.of(), 1)))), Map.entry("getAccount", Map.entry(Set.of(), Map.entry("Account", Map.entry(List.of("String"), 1)))), Map.entry("updatePointFromBattle", Map.entry(Set.of("@Path(\"accounts/{mid}/point\")","@POST"), Map.entry("void", Map.entry(List.of("String","String","int","boolean","String"), 1)))), Map.entry("getAccountValue", Map.entry(Set.of("@Path(\"/{mid}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("getNameValue", Map.entry(Set.of("@Path(\"/{mid}/name\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("getPointValue", Map.entry(Set.of("@Path(\"/{mid}/point\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of("String"), 1)))), Map.entry("signUp", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("changeName", Map.entry(Set.of("@Path(\"/{aid}/name\")","@PUT"), Map.entry("void", Map.entry(List.of("String","String"), 1)))))))); exprectedStructure.put("Members", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("value", "List<Member>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("List<Member>", Map.entry(List.of(), 1)))), Map.entry("getMember", Map.entry(Set.of(), Map.entry("Member", Map.entry(List.of("int"), 1)))), Map.entry("addRoomMember", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testPOS() { try { // check PULL-first ArrayList<CompilationUnit> generatedCode = generateCode("models/POS.model", PushPullValue.PULL); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Points", Map.entry(Set.of("@Path(\"/points\")","@Component"), Map.entry(Map.ofEntries(Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 2)))))))); exprectedStructure.put("History", Map.entry(Set.of("@Path(\"/history\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "List<Integer>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("List<Integer>", Map.entry(List.of(), 1)))), Map.entry("updateFromPayment", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("int"), 1)))), Map.entry("History", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("List<Integer>"), 1)))))))); exprectedStructure.put("Payment", Map.entry(Set.of("@Path(\"/payment\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "int"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("Payment", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int"), 1)))), Map.entry("purchase", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("int"), 3)))))))); exprectedStructure.put("Total", Map.entry(Set.of("@Path(\"/total\")","@Component"), Map.entry(Map.ofEntries(Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 2)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); // check PUSH-first generatedCode = generateCode("models/POS.model", PushPullValue.PUSH); exprectedStructure.clear(); exprectedStructure.put("Total", Map.entry(Set.of("@Path(\"/total\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "int")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("updateFromHistory", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("List<Integer>"), 1)))), Map.entry("Total", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int"), 1)))))))); exprectedStructure.put("History", Map.entry(Set.of("@Path(\"/history\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "List<Integer>"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("List<Integer>", Map.entry(List.of(), 1)))), Map.entry("updateFromPayment", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("int"), 3)))), Map.entry("History", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("List<Integer>"), 1)))))))); exprectedStructure.put("Points", Map.entry(Set.of("@Path(\"/points\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "int")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("updateFromPayment", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("int"), 1)))), Map.entry("Points", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int"), 1)))))))); exprectedStructure.put("Payment", Map.entry(Set.of("@Path(\"/payment\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "int"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("int", Map.entry(List.of(), 1)))), Map.entry("Payment", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("int"), 1)))), Map.entry("purchase", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("int"), 5)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testSimpleTwitter() { try { ArrayList<CompilationUnit> generatedCode = generateCode("models/SimpleTwitter.model", null); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Accounts", Map.entry(Set.of("@Path(\"/accounts\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Account>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Account>", Map.entry(List.of(), 1)))), Map.entry("getAccount", Map.entry(Set.of(), Map.entry("Account", Map.entry(List.of("String"), 1)))), Map.entry("getAccountValue", Map.entry(Set.of("@Path(\"/{accountId}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("getTweetsValue", Map.entry(Set.of("@Path(\"/{accountId}/tweets\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("List<String>", Map.entry(List.of("String"), 1)))), Map.entry("tweet", Map.entry(Set.of("@Path(\"/{accountId}/tweets\")","@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("signUp", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))))))); exprectedStructure.put("Account", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("tweets", "List<String>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getTweets", Map.entry(Set.of(), Map.entry("List<String>", Map.entry(List.of(), 1)))), Map.entry("tweet", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("Account", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("List<String>"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testVotingSystem() { try { ArrayList<CompilationUnit> generatedCode = generateCode("models/VotingSystem.model", null); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Counts", Map.entry(Set.of("@Path(\"/counts\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Object>"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of(), 8)))), Map.entry("Counts", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("Map<String, Object>"), 1)))))))); exprectedStructure.put("Account", Map.entry(Set.of(), Map.entry(Map.ofEntries(Map.entry("vote", "String")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of(), Map.entry("Map<String, Object>", Map.entry(List.of(), 1)))), Map.entry("getVote", Map.entry(Set.of(), Map.entry("String", Map.entry(List.of(), 1)))), Map.entry("cast", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("Account", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("String"), 1)))))))); exprectedStructure.put("Accounts", Map.entry(Set.of("@Path(\"/accounts\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "Map<String, Account>")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Account>", Map.entry(List.of(), 1)))), Map.entry("getAccount", Map.entry(Set.of(), Map.entry("Account", Map.entry(List.of("String"), 1)))), Map.entry("getAccountValue", Map.entry(Set.of("@Path(\"/{aid}\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("Map<String, Object>", Map.entry(List.of("String"), 1)))), Map.entry("getVoteValue", Map.entry(Set.of("@Path(\"/{aid}/vote\")","@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("String", Map.entry(List.of("String"), 1)))), Map.entry("signUp", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("String","String"), 1)))), Map.entry("cast", Map.entry(Set.of("@Path(\"/{aid}/vote\")","@PUT"), Map.entry("void", Map.entry(List.of("String","String"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private void testWeatherObservationSystem() { try { // check PULL-first ArrayList<CompilationUnit> generatedCode = generateCode("models/WeatherObservationSystem.model", PushPullValue.PULL); Map<String, // class name to Entry<Set<String>, // class annotations Entry<Map<String, String>, // field name to type Map<String, // method name to Entry<Set<String>, // class annotations Entry<String, // return type Entry<List<String>, // arg types Integer>>>>>>> // lines of code exprectedStructure = new HashMap<>(); exprectedStructure.put("Highest", Map.entry(Set.of("@Path(\"/highest\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "double")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 1)))), Map.entry("updateFromTemp_f", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("double"), 1)))), Map.entry("Highest", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("double"), 1)))), Map.entry("reset", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("double"), 1)))))))); exprectedStructure.put("Temp_c", Map.entry(Set.of("@Path(\"/temp_c\")","@Component"), Map.entry(Map.ofEntries(Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 2)))))))); exprectedStructure.put("Temp_f", Map.entry(Set.of("@Path(\"/temp_f\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "double"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 1)))), Map.entry("Temp_f", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("double"), 1)))), Map.entry("observe", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("double"), 3)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); // check PUSH-first generatedCode = generateCode("models/WeatherObservationSystem.model", PushPullValue.PUSH); exprectedStructure.clear(); exprectedStructure.put("Temp_c", Map.entry(Set.of("@Path(\"/temp_c\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "double")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 1)))), Map.entry("updateFromTemp_f", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("double"), 1)))), Map.entry("Temp_c", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("double"), 1)))))))); exprectedStructure.put("Temp_f", Map.entry(Set.of("@Path(\"/temp_f\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "double"), Map.entry("client", "Client")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 1)))), Map.entry("Temp_f", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("double"), 1)))), Map.entry("observe", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("double"), 5)))))))); exprectedStructure.put("Highest", Map.entry(Set.of("@Path(\"/highest\")","@Component"), Map.entry(Map.ofEntries(Map.entry("value", "double")), Map.ofEntries(Map.entry("getValue", Map.entry(Set.of("@Produces(MediaType.APPLICATION_JSON)","@GET"), Map.entry("double", Map.entry(List.of(), 1)))), Map.entry("updateFromTemp_f", Map.entry(Set.of("@POST"), Map.entry("void", Map.entry(List.of("double"), 1)))), Map.entry("Highest", Map.entry(Set.of(), Map.entry("void", Map.entry(List.of("double"), 1)))), Map.entry("reset", Map.entry(Set.of("@PUT"), Map.entry("void", Map.entry(List.of("double"), 1)))))))); checkStructure(generatedCode, exprectedStructure); // generateCheckCode(generatedCode); } catch (FileNotFoundException | ExpectedChannel | ExpectedChannelName | ExpectedLeftCurlyBracket | ExpectedInOrOutOrRefOrSubKeyword | ExpectedStateTransition | ExpectedEquals | ExpectedRHSExpression | WrongLHSExpression | WrongRHSExpression | ExpectedRightBracket | ExpectedAssignment | ExpectedRightCurlyBracket | WrongPathExpression | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) { e.printStackTrace(); } } private ArrayList<CompilationUnit> generateCode(String fileName, PushPullValue pushPullValue) throws FileNotFoundException, ExpectedRightBracket, ExpectedChannel, ExpectedChannelName, ExpectedLeftCurlyBracket, ExpectedRightCurlyBracket, ExpectedInOrOutOrRefOrSubKeyword, ExpectedStateTransition, ExpectedEquals, ExpectedRHSExpression, WrongLHSExpression, WrongRHSExpression, ExpectedAssignment, WrongPathExpression, WrongJsonExpression, ExpectedColon, ExpectedDoubleQuotation { File file = new File(fileName); Parser parser = new Parser(new BufferedReader(new FileReader(file))); DataTransferModel model; model = parser.doParse(); DataFlowGraph graph = DataTransferModelAnalyzer.createDataFlowGraphWithStateStoringAttribute(model); DataTransferModelAnalyzer.annotateWithSelectableDataTransferAttiribute(graph); if (pushPullValue != null) { // Select a specified push/pull transfer method if possible. for (Edge e : graph.getEdges()) { if (!((DataFlowEdge) e).isChannelToResource() && ((DataFlowEdge) e).getAttribute() instanceof PushPullAttribute) { PushPullAttribute ppat = (PushPullAttribute) ((DataFlowEdge) e).getAttribute(); ppat.selectOption(pushPullValue); } } } TypeInference.infer(model); DataTransferMethodAnalyzer.decideToStoreResourceStates(graph); ArrayList<CompilationUnit> codetree = JerseyMethodBodyGenerator.doGenerate(graph, model, JerseyCodeGenerator.doGenerate(graph, model)); // ArrayList<CompilationUnit> codetree = new CodeGeneratorFromDataFlowGraph().generateCode(model, graph, new JerseySpecific(), new JavaSpecific()); return codetree; } private void checkStructure(ArrayList<CompilationUnit> generatedCode, Map<String, Entry<Set<String>, Entry<Map<String, String>, Map<String, Entry<Set<String>, Entry<String, Entry<List<String>, Integer>>>>>>> exprectedStructure) { for (var classEnt: exprectedStructure.entrySet()) { String expectedClassName = classEnt.getKey(); Entry<Set<String>, Entry<Map<String, String>, Map<String, Entry<Set<String>, Entry<String, Entry<List<String>, Integer>>>>>> expectedClassInfo = classEnt.getValue(); TypeDeclaration generatedClass = null; for (CompilationUnit cu: generatedCode) { for (TypeDeclaration type: cu.types()) { if (type.getTypeName().equals(expectedClassName)) { generatedClass = type; break; } } } assertNotNull(generatedClass); Set<String> expectedClassAnnotations = expectedClassInfo.getKey(); for (String expectedAnnotation: expectedClassAnnotations) { boolean existsAnnotation = false; for (Annotation generatedAnnotation: generatedClass.getAnnotations()) { if (expectedAnnotation.equals(generatedAnnotation.toString())) { existsAnnotation = true; } } assertTrue(existsAnnotation); } Entry<Map<String, String>, Map<String, Entry<Set<String>, Entry<String, Entry<List<String>, Integer>>>>> expectedClassStructure = expectedClassInfo.getValue(); Map<String, String> exprectedFields = expectedClassStructure.getKey(); Map<String, Entry<Set<String>, Entry<String, Entry<List<String>, Integer>>>> exprectedMethods = expectedClassStructure.getValue(); for (String expectedFieldName: exprectedFields.keySet()) { FieldDeclaration generatedField = null; for (FieldDeclaration field: generatedClass.getFields()) { if (field.getName().equals(expectedFieldName)) { generatedField = field; break; } } assertNotNull(generatedField); String expectedFieldType = exprectedFields.get(expectedFieldName); if (expectedFieldType.equals("void")) { assertNull(generatedField.getType()); } else { assertEquals(expectedFieldType, generatedField.getType().getInterfaceTypeName()); } } for (String expectedMethodName: exprectedMethods.keySet()) { MethodDeclaration generatedMethod= null; for (MethodDeclaration method: generatedClass.getMethods()) { if (method.getName().equals(expectedMethodName)) { generatedMethod = method; break; } } assertNotNull(generatedMethod); Entry<Set<String>, Entry<String, Entry<List<String>, Integer>>> expectedMethodInfo = exprectedMethods.get(expectedMethodName); Set<String> expectedMethodAnnotations = expectedMethodInfo.getKey(); for (String expectedAnnotation: expectedMethodAnnotations) { boolean existsAnnotation = false; for (Annotation generatedAnnotation: generatedMethod.getAnnotations()) { if (expectedAnnotation.replaceAll("\\{.*\\}", "\\{\\}").equals(generatedAnnotation.toString().replaceAll("\\{.*\\}", "\\{\\}"))) { existsAnnotation = true; } } assertTrue(existsAnnotation); } Entry<String, Entry<List<String>, Integer>> expectedMethodSignature = expectedMethodInfo.getValue(); String expectedReturnType = expectedMethodSignature.getKey(); if (expectedReturnType.equals("void")) { if (generatedMethod.getReturnType() != null) { assertEquals(expectedReturnType, generatedMethod.getReturnType().getInterfaceTypeName()); } else { assertNull(generatedMethod.getReturnType()); } } else { assertEquals(expectedReturnType, generatedMethod.getReturnType().getInterfaceTypeName()); } Entry<List<String>, Integer> expectedMethodInfo2 = expectedMethodSignature.getValue(); List<String> expectedArgTypes = expectedMethodInfo2.getKey(); for (String expectedArgType: expectedArgTypes) { boolean existsArg = false; for (VariableDeclaration var: generatedMethod.getParameters()) { if (expectedArgType.equals(var.getType().getInterfaceTypeName())) { existsArg = true; } } assertTrue(existsArg); } int expectedLinesOfCode = expectedMethodInfo2.getValue(); assertEquals(expectedLinesOfCode, generatedMethod.getBody().getStatements().size()); } } } private void generateCheckCode(ArrayList<CompilationUnit> generatedCode) { // exprectedStructure.put("Main", Map.entry(Set.of(), // Map.entry(Map.ofEntries(Map.entry("history", "History"), // Map.entry("total", "Total"), // Map.entry("payment", "Payment"), // Map.entry("points", "Points")), // Map.ofEntries(Map.entry("Main", Map.entry(Set.of(), // Map.entry("void", // Map.entry(List.of(), // 4)))), // Map.entry("getHistory", Map.entry(Set.of(), // Map.entry("List", // Map.entry(List.of(), // 1)))), // Map.entry("getTotal", Map.entry(Set.of(), // Map.entry("int", // Map.entry(List.of(), // 1)))), // Map.entry("getPayment", Map.entry(Set.of(), // Map.entry("int", // Map.entry(List.of(), // 1)))), // Map.entry("purchase", Map.entry(Set.of(), // Map.entry("void", // Map.entry(List.of("int"), // 1)))), // Map.entry("getPoints", Map.entry(Set.of(), // Map.entry("int", // Map.entry(List.of(), // 1)))))))); for (CompilationUnit cu: generatedCode) { for (TypeDeclaration type: cu.types()) { Collection<Annotation> annotations = type.getAnnotations(); List<FieldDeclaration> fields = type.getFields(); List<MethodDeclaration> methods = type.getMethods(); // class annotations if (annotations.size() == 0) { System.out.println("\t\t\texprectedStructure.put(\"" + type.getTypeName() + "\", Map.entry(Set.of(),"); } else { System.out.print("\t\t\texprectedStructure.put(\"" + type.getTypeName() + "\", Map.entry(Set.of("); String delim = ""; for (Annotation annotation: annotations) { System.out.print(delim + "\"" + annotation.toString().replace("\"", "\\\"") + "\""); delim = ","; } System.out.println("),"); } // fields System.out.print("\t\t\t\t\t\t\t\t\t\t\t\t"); for (int j = 0; j < (type.getTypeName().length() + 1) / 4; j++) { System.out.print("\t"); } for (int j = 0; j < (type.getTypeName().length() + 1) % 4; j++) { System.out.print(" "); } if (fields.size() == 0) { System.out.println("Map.entry(Map.ofEntries(),"); } else if (fields.size() == 1) { FieldDeclaration field = fields.get(0); System.out.println("Map.entry(Map.ofEntries(Map.entry(\"" + field.getName() + "\", \"" + field.getType().getInterfaceTypeName() + "\")),"); } else { int i = 0; for (FieldDeclaration field: fields) { if (i == 0) { System.out.println("Map.entry(Map.ofEntries(Map.entry(\"" + field.getName() + "\", \"" + field.getType().getInterfaceTypeName() + "\"),"); } else { System.out.print("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); for (int j = 0; j < (type.getTypeName().length() + 1) / 4; j++) { System.out.print("\t"); } for (int j = 0; j < (type.getTypeName().length() + 1) % 4; j++) { System.out.print(" "); } if (i < fields.size() - 1) { System.out.println("Map.entry(\"" + field.getName() + "\", \"" + field.getType().getInterfaceTypeName() + "\"),"); } else { System.out.println("Map.entry(\"" + field.getName() + "\", \"" + field.getType().getInterfaceTypeName() + "\")),"); } } i++; } } // methods if (methods.size() == 0) { System.out.print("\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); for (int j = 0; j < (type.getTypeName().length() + 3) / 4; j++) { System.out.print("\t"); } for (int j = 0; j < (type.getTypeName().length() + 3) % 4; j++) { System.out.print(" "); } System.out.println("Map.ofEntries())));"); } else { int i = 0; for (MethodDeclaration method: methods) { // method name and method annotations if (i == 0) { System.out.print("\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); for (int j = 0; j < (type.getTypeName().length() + 3) / 4; j++) { System.out.print("\t"); } for (int j = 0; j < (type.getTypeName().length() + 3) % 4; j++) { System.out.print(" "); } Collection<Annotation> methodAnnotations = method.getAnnotations(); if (methodAnnotations.size() == 0) { System.out.println("Map.ofEntries(Map.entry(\"" + method.getName() + "\", Map.entry(Set.of(),"); } else { System.out.print("Map.ofEntries(Map.entry(\"" + method.getName() + "\", Map.entry(Set.of("); String delim = ""; for (Annotation annotation: methodAnnotations) { System.out.print(delim + "\"" + annotation.toString().replace("\"", "\\\"") + "\""); delim = ","; } System.out.println("),"); } } else { System.out.print("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); for (int j = 0; j < (type.getTypeName().length() + 1) / 4; j++) { System.out.print("\t"); } for (int j = 0; j < (type.getTypeName().length() + 1) % 4; j++) { System.out.print(" "); } Collection<Annotation> methodAnnotations = method.getAnnotations(); if (methodAnnotations.size() == 0) { System.out.println("Map.entry(\"" + method.getName() + "\", Map.entry(Set.of(),"); } else { System.out.print("Map.entry(\"" + method.getName() + "\", Map.entry(Set.of("); String delim = ""; for (Annotation annotation: methodAnnotations) { System.out.print(delim + "\"" + annotation.toString().replace("\"", "\\\"") + "\""); delim = ","; } System.out.println("),"); } } // return type System.out.print("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); for (int j = 0; j < (type.getTypeName().length() + method.getName().length() + 3) / 4; j++) { System.out.print("\t"); } for (int j = 0; j < (type.getTypeName().length() + method.getName().length() + 3) % 4; j++) { System.out.print(" "); } if (method.getReturnType() == null) { System.out.println("Map.entry(\"void\", "); } else { System.out.println("Map.entry(\"" + method.getReturnType().getInterfaceTypeName() + "\", "); } // method parameters System.out.print("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); for (int j = 0; j < (type.getTypeName().length() + method.getName().length() + 3) / 4; j++) { System.out.print("\t"); } for (int j = 0; j < (type.getTypeName().length() + method.getName().length() + 3) % 4; j++) { System.out.print(" "); } if (method.getParameters() == null || method.getParameters().size() == 0) { System.out.println("Map.entry(List.of(),"); } else { System.out.print("Map.entry(List.of("); String delim = ""; for (VariableDeclaration arg: method.getParameters()) { System.out.print(delim + "\"" + arg.getType().getInterfaceTypeName() + "\""); delim = ","; } System.out.println("),"); } // method lines of code System.out.print("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); for (int j = 0; j < (type.getTypeName().length() + method.getName().length() + 3) / 4; j++) { System.out.print("\t"); } for (int j = 0; j < (type.getTypeName().length() + method.getName().length() + 3) % 4; j++) { System.out.print(" "); } if (i < methods.size() - 1) { System.out.println("" + method.getBody().getStatements().size() + ")))),"); } else { System.out.println("" + method.getBody().getStatements().size() + "))))))));"); } i++; } } } } } }