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.List;
18 import org.eclipse.winery.common.ModelUtilities;
19 import org.eclipse.winery.model.tosca.TEntityTemplate;
20 import org.eclipse.winery.model.tosca.TNodeTemplate;
21 import org.eclipse.winery.model.tosca.TNodeType;
22 import org.eclipse.winery.model.tosca.TRelationshipTemplate;
23 import org.eclipse.winery.model.tosca.TRelationshipType;
24 import org.eclipse.winery.model.tosca.TTopologyTemplate;
25 import org.eclipse.winery.topologymodeler.addons.topologycompleter.analyzer.TOSCAAnalyzer;
26 import org.eclipse.winery.topologymodeler.addons.topologycompleter.helper.NodeTemplateConnector;
27 import org.eclipse.winery.topologymodeler.addons.topologycompleter.placeholderhandling.PlaceHolderHandler;
30 * This class completes a {@link TTopologyTemplate} containing place holders.
32 public class PlaceHolderCompleter {
35 * The {@link TTopologyTemplate} to be completed
37 TTopologyTemplate topology;
40 * List containing user choices for {@link TRelationshipTemplate}s
42 List<TEntityTemplate> choices;
45 * Whether an user interaction is necessary or not
47 boolean userInteraction;
50 * The last inserted place holder
52 TNodeTemplate placeHolder;
55 * The constructor of the class PlaceHolderCompleter.
58 * the {@link TTopologyTemplate} to be completed
60 public PlaceHolderCompleter(TTopologyTemplate topology) {
61 this.topology = topology;
62 userInteraction = false;
66 * This method completes a {@link TTopologyTemplate} containing place holders.
69 * the contained place holders
70 * @param toscaAnalyzer
71 * the {@link TOSCAAnalyzer} object to access the data model
73 * @return the complete {@link TTopologyTemplate}
75 public List<TTopologyTemplate> completePlaceholderTopology(List<TNodeTemplate> placeHolders, TOSCAAnalyzer toscaAnalyzer) {
77 List<TTopologyTemplate> solutions = new ArrayList<TTopologyTemplate>();
79 for (TNodeTemplate placeHolder : placeHolders) {
81 List<TNodeType> suitableNodeTypes = PlaceHolderHandler.getSuitableNodeTypes(placeHolder, toscaAnalyzer);
83 // if there are more than one solution for an inserted NodeTemplate,
84 // create copies of the topology. The user can choose from them after the completion.
85 TTopologyTemplate topologyCopy = null;
87 for (TNodeType suitableNodeType : suitableNodeTypes) {
88 topologyCopy = new TTopologyTemplate();
89 topologyCopy.getNodeTemplateOrRelationshipTemplate().addAll(topology.getNodeTemplateOrRelationshipTemplate());
91 TNodeTemplate nodeTemplate = ModelUtilities.instantiateNodeTemplate(suitableNodeType);
93 List<TNodeTemplate> sourceTemplates = new ArrayList<>();
95 // contains RelationshipTemplates connecting to a place holder.
96 // These Templates are generic and have to be replaced with
98 List<TRelationshipTemplate> placeholderConnections = new ArrayList<>();
100 TRelationshipTemplate foundTarget = null;
101 for (TEntityTemplate entity : topology.getNodeTemplateOrRelationshipTemplate()) {
102 if (entity instanceof TRelationshipTemplate) {
103 TRelationshipTemplate rt = (TRelationshipTemplate) entity;
104 if (((TNodeTemplate) rt.getTargetElement().getRef()).getId().equals(placeHolder.getId())) {
105 TRelationshipTemplate placeHolderConnection = (TRelationshipTemplate) entity;
106 placeholderConnections.add(placeHolderConnection);
107 sourceTemplates.add((TNodeTemplate) placeHolderConnection.getSourceElement().getRef());
108 } else if (((TNodeTemplate) rt.getSourceElement().getRef()).getId().equals(placeHolder.getId())) {
109 foundTarget = (TRelationshipTemplate) entity;
114 // collect all possible RelationshipTemplates that can be used to connect to the placeholder
115 choices = new ArrayList<>();
117 for (TNodeTemplate sourceTemplate : sourceTemplates) {
118 // find matching RelationshipTypes to connect the Node Templates
119 List<TRelationshipType> suitableRTs = NodeTemplateConnector.findRelationshipType(sourceTemplate, nodeTemplate, toscaAnalyzer, null);
120 for (TRelationshipType rt : suitableRTs) {
121 TRelationshipTemplate relationship = ModelUtilities.instantiateRelationshipTemplate(rt, sourceTemplate, nodeTemplate);
122 choices.add(relationship);
126 // set the source elements of the RelationshipTemplates connecting from the replaced placeholder to other NodeTemplates
127 for (TEntityTemplate entityTemplate : topologyCopy.getNodeTemplateOrRelationshipTemplate()) {
128 if (entityTemplate instanceof TRelationshipTemplate) {
129 TRelationshipTemplate relationshipTemplate = (TRelationshipTemplate) entityTemplate;
130 if (relationshipTemplate.equals(foundTarget)) {
131 foundTarget.getSourceElement().setRef(nodeTemplate);
136 // remove the generic connections to the place holder
137 topologyCopy.getNodeTemplateOrRelationshipTemplate().removeAll(placeholderConnections);
139 // there are more than one possible Relationship Templates to connect to the inserted NodeTemplate(s), so
140 // interrupt the completion and ask the user which one to insert
141 if (choices.size() > 1 && sourceTemplates.size() == 1) {
143 choices.add(sourceTemplates.get(0));
144 choices.add(nodeTemplate);
145 topologyCopy.getNodeTemplateOrRelationshipTemplate().remove(placeHolder);
147 userInteraction = true;
148 this.placeHolder = placeHolder;
150 } else if (choices.size() == 1 || sourceTemplates.size() > 1) {
151 // replace the place holder with an actual NodeTemplate
152 topologyCopy.getNodeTemplateOrRelationshipTemplate().addAll(choices);
153 topologyCopy.getNodeTemplateOrRelationshipTemplate().add(nodeTemplate);
154 topologyCopy.getNodeTemplateOrRelationshipTemplate().remove(placeHolder);
156 solutions.add(topologyCopy);
163 * Returns the replaced place holder.
165 * @return the place holder
167 public TNodeTemplate getPlaceHolder() {
172 * Returns whether an user interaction is necessary or not.
174 * @return the field userInteraction
176 public boolean getUserInteraction() {
177 return userInteraction;
181 * Possible Relationship Template choices.
183 * @return the field choices
185 public List<TEntityTemplate> getChoices() {