b8cc7457e1f9fcb4038037b295122f0ef6171b3c
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.topologymodeler / src / main / java / org / eclipse / winery / topologymodeler / addons / topologycompleter / topologycompletion / completer / StepByStepCompleter.java
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
8  *
9  * Contributors:
10  *    Pascal Hirmer - initial API and implementation
11  *******************************************************************************/
12
13 package org.eclipse.winery.topologymodeler.addons.topologycompleter.topologycompletion.completer;
14
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20
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;
33
34 /**
35  * This class handles topologies that are completed step by step
36  */
37 public class StepByStepCompleter {
38
39         /**
40          * the topology to be completed
41          */
42         TTopologyTemplate topology;
43
44         /**
45          * the Node and RelationshipTemplates chosen by the user in every step
46          */
47         Map<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>> templateChoices;
48
49         /**
50          * the last inserted place holder to be deleted
51          */
52         private TNodeTemplate placeHolder;
53
54         /**
55          * The constructor of the class.
56          *
57          * @param topology
58          *            the {@link TTopologyTemplate} to be completed
59          */
60         public StepByStepCompleter(TTopologyTemplate topology) {
61                 this.topology = topology;
62         }
63
64         /**
65          * This method is called when a topology containing {@link TRequirement}s is completed step by step.
66          *
67          * @param unfulfilledRequirements
68          *            a list of unfulfilled requirements
69          * @param placeHolders
70          *            a list of place holders to be fulfilled
71          * @param toscaAnalyzer
72          *                        the {@link TOSCAAnalyzer} object to access the data model
73          */
74         public void completeTopologyStepByStep(Map<TRequirement, TNodeTemplate> unfulfilledRequirements, TOSCAAnalyzer toscaAnalyzer) {
75
76                 Set<TRequirement> requirements = unfulfilledRequirements.keySet();
77
78                 TNodeTemplate nodeTemplate = null;
79
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);
86                                 }
87                         }
88
89                         List<TNodeType> possibleNodeTypes = Utils.matchRequirementAndCapability(requirement, toscaAnalyzer);
90
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);
96                         }
97
98                         TNodeTemplate correspondingNodeTemplate = unfulfilledRequirements.get(requirement);
99
100                         Map<TNodeTemplate, List<TEntityTemplate>> entityTemplates = new HashMap<>();
101
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);
109                                 }
110                                 entityTemplates.put(possibleTemplate, choices);
111                         }
112
113                         templateChoices = new HashMap<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>>();
114                         templateChoices.put(correspondingNodeTemplate, entityTemplates);
115
116                         // let the user decide which template shall be inserted
117                         break;
118                 }
119
120         }
121
122         /**
123          * Completes a place holder {@link TTopologyTemplate} step by step.
124          *
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.
130          */
131         public TRelationshipTemplate completeWildcardTopologyStepByStep(List<TNodeTemplate> placeHolders, TOSCAAnalyzer toscaAnalyzer) {
132
133                 // take the first place holder, the order doesn't matter in the step by step approach
134                 TNodeTemplate placeHolder = placeHolders.get(0);
135
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);
142                 }
143
144                 /**
145                  * map containing the choices for the user selection
146                  */
147                 Map<TNodeTemplate, List<TEntityTemplate>> entityTemplates = new HashMap<>();
148
149                 TNodeTemplate sourceTemplate = null;
150
151                 // the RelationshipTemplate connecting to the placeholder
152                 TRelationshipTemplate connectingRelationshipTemplate = null;
153
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();
160                                 }
161                         }
162                 }
163
164                 for (TNodeTemplate nodeTemplate : suitableNodeTemplates) {
165
166                         List<TEntityTemplate> choices = new ArrayList<>();
167
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);
173                         }
174                         entityTemplates.put(nodeTemplate, choices);
175                 }
176
177                 templateChoices = new HashMap<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>>();
178                 templateChoices.put(sourceTemplate, entityTemplates);
179
180                 this.placeHolder = placeHolder;
181
182                 return connectingRelationshipTemplate;
183
184         }
185
186         /**
187          * Returns a map containing the choices for the user selection when the topology is completed step by step.
188          *
189          * @return the field ntChoices
190          */
191         public Map<TNodeTemplate, Map<TNodeTemplate, List<TEntityTemplate>>> getTemplateChoices() {
192                 return templateChoices;
193         }
194
195         /**
196          * Returns the replaced place holder to remove it from the topology.
197          *
198          * @return the place holder
199          */
200         public TNodeTemplate getPlaceHolder() {
201                 return placeHolder;
202         }
203 }