Merge pull request #79 from nitta-lab/updateHierarchicalResources
UpdateHierarchicalResources
commit 5eca8206c6931868b6fcf5625c3e6ab9591fccc9
2 parents f33fca5 + 01af0c3
okazaki takehiro authored on 9 Oct 2023
Showing 10 changed files
View
4
AlgebraicDataflowArchitectureModel/models/CustomerOffice.model
channel CIO_AddCustomer {
out customers(db:Map, addCustomer(uid:Str, off:Str)) == insert(db, uid, {"off": off})
}
 
channel CIO_AddCampany {
out companies(db:Map, addCampany(cid:Str, add:Str)) == insert(db, cid, {"add": add})
}
 
channel CIO_SetCustomerOff(uid:Str) {
out customers.{uid}.off(cid:Str, setOff(cid2)) == cid2
View
158
AlgebraicDataflowArchitectureModel/src/generators/CodeGenerator.java
public ArrayList<CompilationUnit> generateCode(DataTransferModel model, DataFlowGraph flowGraph, ILanguageSpecific langSpec) {
CodeGenerator.langSpec = langSpec;
ArrayList<CompilationUnit> codes = new ArrayList<>();
// Get the dependency among root nodes.
Map<ResourceHierarchy, Set<ResourceHierarchy>> dependedRootComponentGraph = getDependedRootComponentGraph(model);
// Sort the all components.
ArrayList<ResourceNode> components = determineComponentOrder(flowGraph);
ArrayList<ResourceNode> components = determineComponentOrder(flowGraph, dependedRootComponentGraph);
// Add the main component.
if (mainTypeName == null) {
mainTypeName = langSpec.getMainComponentName();
CompilationUnit mainCU = langSpec.newCompilationUnit(mainComponent);
codes.add(mainCU);
// Generate the other components.
generateCodeFromFlowGraph(model, flowGraph, components, mainComponent, mainConstructor, codes, langSpec);
generateCodeFromFlowGraph(model, flowGraph, components, dependedRootComponentGraph, mainComponent, mainConstructor, codes, langSpec);
return codes;
}
public abstract void generateCodeFromFlowGraph(DataTransferModel model, DataFlowGraph flowGraph, ArrayList<ResourceNode> components,
public abstract void generateCodeFromFlowGraph(DataTransferModel model, DataFlowGraph flowGraph, ArrayList<ResourceNode> components, Map<ResourceHierarchy, Set<ResourceHierarchy>> dependedRootComponentGraph,
TypeDeclaration mainComponent, MethodDeclaration mainConstructor, ArrayList<CompilationUnit> codes, ILanguageSpecific langSpec);
private static ArrayList<ResourceNode> determineComponentOrder(DataFlowGraph graph) {
private static Map<ResourceHierarchy, Set<ResourceHierarchy>> getDependedRootComponentGraph(DataTransferModel model) {
Map<ResourceHierarchy, Set<ResourceHierarchy>> dependedComponentGraph = new HashMap<>();
for (Channel ch: model.getChannels()) {
DataTransferChannel dtCh = (DataTransferChannel) ch;
Set<ResourceHierarchy> inRes = new HashSet<>();
Set<ResourceHierarchy> outRes = new HashSet<>();
for (ChannelMember cm: dtCh.getChannelMembers()) {
if (cm.isOutside()) {
outRes.add(cm.getResource().getResourceHierarchy());
} else {
inRes.add(cm.getResource().getResourceHierarchy());
}
}
if (outRes.size() > 0 && inRes.size() > 0) {
for (ResourceHierarchy out: outRes) {
for (ResourceHierarchy in: inRes) {
Set<ResourceHierarchy> dependings = dependedComponentGraph.get(out.getRoot());
if (dependings == null) {
dependings = new HashSet<>();
dependedComponentGraph.put(out.getRoot(), dependings);
}
dependings.add(in.getRoot());
}
}
}
}
return dependedComponentGraph;
}
private static ArrayList<ResourceNode> determineComponentOrder(DataFlowGraph graph, Map<ResourceHierarchy, Set<ResourceHierarchy>> dependedRootComponentGraph) {
ArrayList<ResourceNode> objects = new ArrayList<>();
Set<ResourceNode> visited = new HashSet<>();
Collection<ResourceNode> allNodes = graph.getResourceNodes();
for (ResourceNode resNode: allNodes) {
topologicalSort(allNodes, resNode, visited, objects);
topologicalSort(resNode, allNodes, dependedRootComponentGraph, visited, objects);
}
return objects;
}
private static void topologicalSort(Collection<ResourceNode> allNodes, ResourceNode curResNode, Set<ResourceNode> visited, List<ResourceNode> orderedList) {
private static void topologicalSort(ResourceNode curResNode, Collection<ResourceNode> allNodes, Map<ResourceHierarchy, Set<ResourceHierarchy>> dependedRootComponentGraph, Set<ResourceNode> visited, List<ResourceNode> orderedList) {
if (visited.contains(curResNode)) return;
visited.add(curResNode);
// a caller is before the callee
// A caller is before the callee
// For each incoming PUSH transfer.
for (Edge chToRes: curResNode.getInEdges()) {
for (Edge resToCh: chToRes.getSource().getInEdges()) {
if (!(resToCh instanceof DataFlowEdge) || ((PushPullAttribute)((DataFlowEdge) resToCh).getAttribute()).getOptions().get(0) == PushPullValue.PUSH) {
topologicalSort(allNodes, (ResourceNode) resToCh.getSource(), visited, orderedList);
}
}
}
topologicalSort((ResourceNode) resToCh.getSource(), allNodes, dependedRootComponentGraph, visited, orderedList);
}
}
}
// For each outgoing PULL transfer.
if (curResNode instanceof ResourceNode) {
for (Edge resToCh: curResNode.getOutEdges()) {
DataFlowEdge de = (DataFlowEdge) resToCh;
if (((PushPullAttribute) de.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) {
for (Edge chToRes : resToCh.getDestination().getOutEdges()) {
topologicalSort(allNodes, (ResourceNode) chToRes.getDestination(), visited, orderedList);
}
}
}
}
// For reference resources.
topologicalSort((ResourceNode) chToRes.getDestination(), allNodes, dependedRootComponentGraph, visited, orderedList);
}
}
}
}
// For each depending root node.
if (curResNode instanceof ResourceNode && dependedRootComponentGraph.get(curResNode.getResourceHierarchy()) != null) {
for (ResourceHierarchy dependingRes: dependedRootComponentGraph.get(curResNode.getResourceHierarchy())) {
for (ResourceNode rootNode: allNodes) {
ResourceHierarchy rootRes = rootNode.getResourceHierarchy();
if (rootRes.getParent() == null && rootRes.equals(dependingRes)) {
topologicalSort(rootNode, allNodes, dependedRootComponentGraph, visited, orderedList);
}
}
}
}
// For each reference resource.
ResourceNode cn = null;
if (curResNode instanceof ResourceNode) {
cn = (ResourceNode) curResNode;
}
for (Edge resToCh: resNode.getOutEdges()) {
ChannelNode chNode = (ChannelNode) resToCh.getDestination();
for (ChannelMember m: chNode.getChannel().getReferenceChannelMembers()) {
if (m.getResource().equals(curResNode.getOutSideResource())) {
topologicalSort(allNodes, resNode, visited, orderedList);
topologicalSort(resNode, allNodes, dependedRootComponentGraph, visited, orderedList);
}
}
}
}
orderedList.add(0, curResNode);
}
 
protected void updateMainComponent(DataTransferModel model, TypeDeclaration mainType, MethodDeclaration mainConstructor, Node componentNode,
final List<ResourcePath> depends, ILanguageSpecific langSpec) {
final List<ResourceHierarchy> depends, ILanguageSpecific langSpec) {
// Declare the field to refer to each object in the main type.
ResourceNode resNode = null;
String nodeName = null;
if (componentNode instanceof ResourceNode) {
mainType.addField(refField);
}
// Add a statement to instantiate each object to the main constructor.
List<String> parameters = new ArrayList<>();
for (ResourcePath res: depends) {
for (ResourceHierarchy res: depends) {
// For the callee objects (the destination resource of push transfer or the source resource of pull transfer).
parameters.add(res.getResourceName());
}
// For the refs.
Set<ResourcePath> refs = new HashSet<>();
for (Channel cg : model.getChannels()) {
DataTransferChannel ch = (DataTransferChannel) cg;
if (ch.getInputResources().contains(resNode.getOutSideResource())) {
for (ResourcePath id: ch.getReferenceResources()) {
if (!refs.contains(id) && !depends.contains(id)) {
refs.add(id);
String refResName = id.getResourceName();
for (ResourcePath resPath: ch.getReferenceResources()) {
if (!refs.contains(resPath) && !depends.contains(resPath.getResourceHierarchy())) {
refs.add(resPath);
String refResName = resPath.getResourceName();
parameters.add(refResName);
}
}
}
}
mainConstructorBody.addStatement(langSpec.getFieldAccessor(nodeName) + langSpec.getAssignment() + langSpec.getConstructorInvocation(componentName, parameters) + langSpec.getStatementDelimiter());
}
 
protected ResourcePath addReference(TypeDeclaration component, MethodDeclaration constructor, ResourcePath dstRes, ILanguageSpecific langSpec) {
if (!generatesComponent(dstRes.getResourceHierarchy())) {
protected ResourceHierarchy addReference(TypeDeclaration component, MethodDeclaration constructor, ResourceHierarchy dstRes, ILanguageSpecific langSpec) {
if (!generatesComponent(dstRes)) {
dstRes = dstRes.getParent();
}
String dstComponentName = getComponentName(dstRes.getResourceHierarchy(), langSpec);
String dstComponentName = getComponentName(dstRes, langSpec);
if (dstComponentName != null) {
String dstNodeName = langSpec.toVariableName(dstComponentName);
if (langSpec.declareField()) {
// Declare a field to refer to another component.
String fieldName = langSpec.toVariableName(childTypeName);
Term childGetter = null;
if ((child.getChildren() == null || child.getChildren().size() == 0) && child.getNumParameters() == 0) {
// the child is not a class
childGetter = new Field(fieldName, getImplStateType(child, langSpec));
childGetter = new Term(new Symbol("get" + childTypeName, 1, Symbol.Type.METHOD));
childGetter.addChild(new Constant("this"));
} else {
// the child is a class
childGetter = new Term(new Symbol(getterOfResourceState, 1, Symbol.Type.METHOD));
childGetter.addChild(new Field(fieldName, getImplStateType(child, langSpec)));
mainComponent.addMethod(accessor);
}
 
protected void declareFieldsToReferenceResources(DataTransferModel model, ResourceNode resourceNode, TypeDeclaration component, MethodDeclaration constructor,
final List<ResourcePath> depends, ILanguageSpecific langSpec) {
final List<ResourceHierarchy> depends, ILanguageSpecific langSpec) {
Set<ResourcePath> refs = new HashSet<>();
for (Channel ch : model.getChannels()) {
DataTransferChannel c = (DataTransferChannel) ch;
if (c.getInputResources().contains(resourceNode.getOutSideResource())) {
for (ResourcePath res: c.getReferenceResources()) {
if (!refs.contains(res) && !depends.contains(res)) {
if (!refs.contains(res) && !depends.contains(res.getResourceHierarchy())) {
refs.add(res);
String refResName = langSpec.toComponentName(res.getResourceName());
component.addField(langSpec.newFieldDeclaration(new Type(refResName, refResName), res.getResourceName()));
constructor.addParameter(langSpec.newVariableDeclaration(new Type(refResName, refResName), res.getResourceName()));
}
}
}
}
protected MethodDeclaration getConstructor(TypeDeclaration component) {
for (MethodDeclaration m: component.getMethods()) {
if (m.isConstructor()) return m;
}
return null;
}
protected MethodDeclaration getUpdateMethod(Edge inEdge, TypeDeclaration component,
Map<Edge, Map<PushPullValue, List<ResourceNode>>> dataFlowInform, ILanguageSpecific langSpec) {
List<ResourceNode> passedResoueces = dataFlowInform.get(inEdge).get(PushPullValue.PUSH);
View
AlgebraicDataflowArchitectureModel/src/generators/CodeGeneratorFromDataFlowGraph.java
View
AlgebraicDataflowArchitectureModel/src/generators/JavaCodeGenerator.java
View
AlgebraicDataflowArchitectureModel/src/generators/JavaMethodBodyGenerator.java
View
AlgebraicDataflowArchitectureModel/src/generators/JerseyCodeGenerator.java
View
AlgebraicDataflowArchitectureModel/src/generators/JerseyMethodBodyGenerator.java
View
AlgebraicDataflowArchitectureModel/src/models/algebra/Type.java
View
AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/DataConstraintModel.java
View
AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/JsonAccessor.java