diff --git a/AlgebraicDataflowArchitectureModel/models/OnlineBattleGame.model b/AlgebraicDataflowArchitectureModel/models/OnlineBattleGame.model new file mode 100644 index 0000000..ceb7100 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/models/OnlineBattleGame.model @@ -0,0 +1,31 @@ +channel CIO_Signup{ + out accounts(adb:Map, signUp(aid:Str, name:Str)) == insert(adb, aid, {"name": name}) +} + +channel CIO_ChangeName(aid:Str) { + out accounts.{aid}.name(prev_name:Str, changeName(name)) == name +} + +channel CIO_CreateRoom { + out rooms(rdb:Map, createRoom(rid:Str, blue_id:Str, red_id:Str)) == insert(rdb, rid, {"blue_id": blue_id, "red_id": red_id}) +} + +channel CIO_ChangeRed_id(rid:Str) { + out rooms.{rid}.red_id(prev_red_id:Str, changeRed_id(red_id)) == red_id +} + +channel CIO_ChangeBlue_id(rid:Str) { + out rooms.{rid}.blue_id(prev_blue_id:Str, changeBlue_id(blue_id)) == blue_id +} + +channel C_red(rid:Str) { + in rooms.{rid}.red_id(prev_aid:Str, sync(aid, name)) == aid + in accounts.{aid}.name(prev_name:Str, sync(aid, name)) == name + out rooms.{rid}.red_name(prev_name:Str, sync(aid, name)) == name +} + +channel C_blue(rid:Str) { + in rooms.{rid}.blue_id(prev_aid:Str, sync(aid, name)) == aid + in accounts.{aid}.name(prev_name:Str, sync(aid, name)) == name + out rooms.{rid}.blue_name(prev_name:Str, sync(aid, name)) == name +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index 21220f2..2969692 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -1949,38 +1949,40 @@ if (idx == 3) { // exp is a json argument (0:t = addMember(3:json, 1:key, 2:value)). Type jsonType = json.get(System.identityHashCode(jsonMemberGroup)); - Map memberTypes = new HashMap<>(jsonMemberTypes.get(jsonType)); - Map argMemberTypes = new HashMap<>(memberTypes); - String keyName = null; - Type valueType = null; - if (jsonMemberGroup.get(1) instanceof Constant) { - keyName = ((Constant) jsonMemberGroup.get(1)).getSymbol().getName(); - valueType = ((Constant) jsonMemberGroup.get(1)).getType(); - argMemberTypes.remove(keyName); - } - Type jsonArgType = jsonTypes.get(argMemberTypes); - Type newJsonArgType = getExpTypeIfUpdatable(jsonArgType, exp); - if (newJsonArgType != null && keyName != null) { - // Propagate an update of a json arg's type to its container's (json's) type. - argMemberTypes = ((JsonType) newJsonArgType).getMemberTypes(); - argMemberTypes.put(keyName, valueType); - memberTypes.putAll(argMemberTypes); - Type newJsonType = jsonTypes.get(memberTypes); - if (newJsonType == null) { - // Create new json type. - newJsonType = createNewJsonType(memberTypes, jsonType); + if (jsonType != null && jsonMemberTypes.get(jsonType) != null) { + Map memberTypes = new HashMap<>(jsonMemberTypes.get(jsonType)); + Map argMemberTypes = new HashMap<>(memberTypes); + String keyName = null; + Type valueType = null; + if (jsonMemberGroup.get(1) instanceof Constant) { + keyName = ((Constant) jsonMemberGroup.get(1)).getSymbol().getName(); + valueType = ((Constant) jsonMemberGroup.get(1)).getType(); + argMemberTypes.remove(keyName); } - // Update the type of the json term and record the updated expression. - Map updateExps = getUpdateSet(updateFromJson, jsonMemberGroup); - Expression jsonExp = jsonMemberGroup.get(0); - if (jsonExp instanceof Variable) { - ((Variable) jsonExp).setType(newJsonType); - updateExps.put(System.identityHashCode(jsonExp), jsonExp); - } else if (jsonExp instanceof Term) { - ((Term) jsonExp).setType(newJsonType); - updateExps.put(System.identityHashCode(jsonExp), jsonExp); + Type jsonArgType = jsonTypes.get(argMemberTypes); + Type newJsonArgType = getExpTypeIfUpdatable(jsonArgType, exp); + if (newJsonArgType != null && keyName != null) { + // Propagate an update of a json arg's type to its container's (json's) type. + argMemberTypes = ((JsonType) newJsonArgType).getMemberTypes(); + argMemberTypes.put(keyName, valueType); + memberTypes.putAll(argMemberTypes); + Type newJsonType = jsonTypes.get(memberTypes); + if (newJsonType == null) { + // Create new json type. + newJsonType = createNewJsonType(memberTypes, jsonType); + } + // Update the type of the json term and record the updated expression. + Map updateExps = getUpdateSet(updateFromJson, jsonMemberGroup); + Expression jsonExp = jsonMemberGroup.get(0); + if (jsonExp instanceof Variable) { + ((Variable) jsonExp).setType(newJsonType); + updateExps.put(System.identityHashCode(jsonExp), jsonExp); + } else if (jsonExp instanceof Term) { + ((Term) jsonExp).setType(newJsonType); + updateExps.put(System.identityHashCode(jsonExp), jsonExp); + } + json.put(System.identityHashCode(jsonMemberGroup), newJsonType); } - json.put(System.identityHashCode(jsonMemberGroup), newJsonType); } } else if (idx == 2) { // exp is a value (0:t = addMember(3:json, 1:key, 2:value) or 2:value = dot(0:list/map, 1:key)). diff --git a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java index 9aa4b39..89f87e9 100644 --- a/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java @@ -633,7 +633,27 @@ // Add leaf reference fields to the parent components. for (Map.Entry entry: fields) { - resourceComponents.get(entry.getKey()).addField(entry.getValue()); + ResourceHierarchy resource = entry.getKey(); + FieldDeclaration field = entry.getValue(); + TypeDeclaration component = resourceComponents.get(resource); + boolean existsField = false; + for (FieldDeclaration fld: component.getFields()) { + if (fld.getName().equals(field.getName())) { + existsField = true; + break; + } + } + if (!existsField) { + component.addField(field); + if (field.getType().equals(typeClient)) { + for (CompilationUnit cu: codes) { + if (cu.types().contains(component)) { + cu.addImport(new ImportDeclaration("javax.ws.rs.client.*")); + break; + } + } + } + } } // Add constructor parameters to the ancestor components.