1 /*******************************************************************************
2 * Copyright (c) 2013 Pascal Hirmer.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * and the Apache License 2.0 which both accompany this distribution,
6 * and are available at http://www.eclipse.org/legal/epl-v10.html
7 * and http://www.apache.org/licenses/LICENSE-2.0
10 * Pascal Hirmer - initial API and implementation
11 *******************************************************************************/
13 package org.eclipse.winery.topologymodeler.addons.topologycompleter.topologycompletion.completer;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
21 import org.eclipse.winery.common.ModelUtilities;
22 import org.eclipse.winery.model.tosca.TEntityTemplate;
23 import org.eclipse.winery.model.tosca.TNodeTemplate;
24 import org.eclipse.winery.model.tosca.TNodeType;
25 import org.eclipse.winery.model.tosca.TRelationshipTemplate;
26 import org.eclipse.winery.model.tosca.TRelationshipType;
27 import org.eclipse.winery.model.tosca.TRequirement;
28 import org.eclipse.winery.model.tosca.TTopologyTemplate;
29 import org.eclipse.winery.topologymodeler.addons.topologycompleter.analyzer.TOSCAAnalyzer;
30 import org.eclipse.winery.topologymodeler.addons.topologycompleter.helper.NodeTemplateConnector;
31 import org.eclipse.winery.topologymodeler.addons.topologycompleter.helper.Utils;
32 import org.eclipse.winery.topologymodeler.addons.topologycompleter.placeholderhandling.PlaceHolderHandler;
35 * This class handles topologies that are completed step by step
37 public class StepByStepCompleter {
40 * the topology to be completed
42 TTopologyTemplate topology;
45 * the Node and RelationshipTemplates chosen by the user in every step
47 Map<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>> templateChoices;
50 * the last inserted place holder to be deleted
52 private TNodeTemplate placeHolder;
55 * The constructor of the class.
58 * the {@link TTopologyTemplate} to be completed
60 public StepByStepCompleter(TTopologyTemplate topology) {
61 this.topology = topology;
65 * This method is called when a topology containing {@link TRequirement}s is completed step by step.
67 * @param unfulfilledRequirements
68 * a list of unfulfilled requirements
70 * a list of place holders to be fulfilled
71 * @param toscaAnalyzer
72 * the {@link TOSCAAnalyzer} object to access the data model
74 public void completeTopologyStepByStep(Map<TRequirement, TNodeTemplate> unfulfilledRequirements, TOSCAAnalyzer toscaAnalyzer) {
76 Set<TRequirement> requirements = unfulfilledRequirements.keySet();
78 TNodeTemplate nodeTemplate = null;
80 for (TRequirement requirement : requirements) {
81 // remove the requirement from the NodeTemplate
82 TNodeTemplate requirementTemplate = unfulfilledRequirements.get(requirement);
83 for (TEntityTemplate element : topology.getNodeTemplateOrRelationshipTemplate()) {
84 if (requirementTemplate.getId().equals(element.getId())) {
85 ((TNodeTemplate) element).getRequirements().getRequirement().remove(requirement);
89 List<TNodeType> possibleNodeTypes = Utils.matchRequirementAndCapability(requirement, toscaAnalyzer);
91 // create a NodeTemplate for each matching node type
92 List<TNodeTemplate> possibleTemplates = new ArrayList<>();
93 for (TNodeType possibleType : possibleNodeTypes) {
94 nodeTemplate = ModelUtilities.instantiateNodeTemplate(possibleType);
95 possibleTemplates.add(nodeTemplate);
98 TNodeTemplate correspondingNodeTemplate = unfulfilledRequirements.get(requirement);
100 Map<TNodeTemplate, List<TEntityTemplate>> entityTemplates = new HashMap<>();
102 // add all possible choices to a list and return it to the user
103 for (TNodeTemplate possibleTemplate : possibleTemplates) {
104 List<TEntityTemplate> choices = new ArrayList<TEntityTemplate>();
105 List<TRelationshipType> suitableRTs = NodeTemplateConnector.findRelationshipType(correspondingNodeTemplate, possibleTemplate, toscaAnalyzer, requirement);
106 for (TRelationshipType rt : suitableRTs) {
107 TRelationshipTemplate relationship = ModelUtilities.instantiateRelationshipTemplate(rt, correspondingNodeTemplate, possibleTemplate);
108 choices.add(relationship);
110 entityTemplates.put(possibleTemplate, choices);
113 templateChoices = new HashMap<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>>();
114 templateChoices.put(correspondingNodeTemplate, entityTemplates);
116 // let the user decide which template shall be inserted
123 * Completes a place holder {@link TTopologyTemplate} step by step.
125 * @param placeHolders
126 * the place holders of the topology
127 * @param toscaAnalyzer
128 * the {@link TOSCAAnalyzer} object to access the data model.
129 * @return the generic {@link TRelationshipTemplate} which connects to the place holder.
131 public TRelationshipTemplate completeWildcardTopologyStepByStep(List<TNodeTemplate> placeHolders, TOSCAAnalyzer toscaAnalyzer) {
133 // take the first place holder, the order doesn't matter in the step by step approach
134 TNodeTemplate placeHolder = placeHolders.get(0);
136 // get suitable NodeTypes for a placeholder and instantiate NodeTemplates
137 List<TNodeType> suitableNodeTypes = PlaceHolderHandler.getSuitableNodeTypes(placeHolder, toscaAnalyzer);
138 List<TNodeTemplate> suitableNodeTemplates = new ArrayList<TNodeTemplate>();
139 for (TNodeType suitableNodeType : suitableNodeTypes) {
140 TNodeTemplate nodeTemplate = ModelUtilities.instantiateNodeTemplate(suitableNodeType);
141 suitableNodeTemplates.add(nodeTemplate);
145 * map containing the choices for the user selection
147 Map<TNodeTemplate, List<TEntityTemplate>> entityTemplates = new HashMap<>();
149 TNodeTemplate sourceTemplate = null;
151 // the RelationshipTemplate connecting to the placeholder
152 TRelationshipTemplate connectingRelationshipTemplate = null;
154 for (TEntityTemplate entity : topology.getNodeTemplateOrRelationshipTemplate()) {
155 if (entity instanceof TRelationshipTemplate) {
156 TRelationshipTemplate rt = (TRelationshipTemplate) entity;
157 if (((TNodeTemplate) rt.getTargetElement().getRef()).getId().equals(placeHolder.getId())) {
158 connectingRelationshipTemplate = (TRelationshipTemplate) entity;
159 sourceTemplate = (TNodeTemplate) connectingRelationshipTemplate.getSourceElement().getRef();
164 for (TNodeTemplate nodeTemplate : suitableNodeTemplates) {
166 List<TEntityTemplate> choices = new ArrayList<>();
168 // find matching RelationshipTypes to connect the Node Templates
169 List<TRelationshipType> suitableRTs = NodeTemplateConnector.findRelationshipType(sourceTemplate, nodeTemplate, toscaAnalyzer, null);
170 for (TRelationshipType rt : suitableRTs) {
171 TRelationshipTemplate relationship = ModelUtilities.instantiateRelationshipTemplate(rt, sourceTemplate, nodeTemplate);
172 choices.add(relationship);
174 entityTemplates.put(nodeTemplate, choices);
177 templateChoices = new HashMap<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>>();
178 templateChoices.put(sourceTemplate, entityTemplates);
180 this.placeHolder = placeHolder;
182 return connectingRelationshipTemplate;
187 * Returns a map containing the choices for the user selection when the topology is completed step by step.
189 * @return the field ntChoices
191 public Map<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>> getTemplateChoices() {
192 return templateChoices;
196 * Returns the replaced place holder to remove it from the topology.
198 * @return the place holder
200 public TNodeTemplate getPlaceHolder() {