cc5c564f60f5a8db4a3966ec98efdc40c7b10b5b
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.topologymodeler / src / main / webapp / js / winery-topologymodeler.js
1 /*******************************************************************************
2  * Copyright (c) 2012-2013,2015 University of Stuttgart.
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  *    Oliver Kopp - initial API and implementation and/or initial documentation
11  *    Yves Schubert - switch to bootstrap 3
12  *******************************************************************************/
13
14 function getQName(qnameStr) {
15         var pos = qnameStr.indexOf("}");
16         var namespace = qnameStr.substring(1, pos);
17         var localName = qnameStr.substring(pos+1);
18         var res = {
19                         "namespace": namespace,
20                         "localName": localName
21         };
22         return res;
23 }
24
25 /**
26  * @param attributeName an attribute with a value in the form prefix:localname
27  * @param xmlElement a DOM element (offering the method lookupNamespaceURI)
28  * @return { ns: namespace, id: id }
29  */
30 function getNSAndId(attributeName, xmlElement) {
31         var attributeValue = xmlElement.getAttribute(attributeName);
32         var i = attributeValue.indexOf(":");
33         var prefix = attributeValue.substring(0, i);
34         var localName = attributeValue.substring(i+1);
35         var ns = xmlElement.lookupNamespaceURI(prefix);
36         var res = {
37                 ns : ns,
38                 id: localName
39         };
40         return res;
41 }
42
43 /**
44  * @param el a href element
45  * @param pathComponent the path element "artifacttemplates" or "artifacttypes"
46  * @param attributeName the name of the attribute to read from the given xmlElement
47  * @param xmlElement used to resolve a namespace prefix to a full namespace URI
48  */
49 function addHref(el, pathComponent, attributeName, xmlElement) {
50         var nsAndId = getNSAndId(attributeName, xmlElement);
51         var loc = winery.repositoryURL + "/" + pathComponent + "/" + encodeID(nsAndId.ns) + "/" + encodeID(nsAndId.id);
52         el.attr("href", loc);
53 }
54
55 var currentlySelectedDeploymentArtifactDiv;
56
57 /**
58  * Sets global variables currentlySelectedNodeTemplate and currentlySelectedDeploymentArtifactDiv
59  */
60 function showDeploymentArtifactInformation(nodeTemplateId, deploymentArtifactName) {
61         currentlySelectedNodeTemplate = nodeTemplateId;
62         var daDiv = $("#" + nodeTemplateId).children("div.deploymentArtifactsContainer").children("div.content").children("div.deploymentArtifact").children("div.name:contains(" + deploymentArtifactName + ")").parent();
63         currentlySelectedDeploymentArtifactDiv = daDiv;
64         var xml = daDiv.children("textarea").val();
65
66         // get values to display directly from the "UI" instead of parsing the XML and asking the server for appropriate names
67         var daArtifactTemplateName = daDiv.children("div.artifactTemplate").text();
68         var daArtifactTypeName = daDiv.children("div.artifactType").text();
69
70         // determine URLs
71         require(["winery-support-common"], function(wsc) {
72                 xmlDoc = wsc.getDocument(xml);
73                 da = xmlDoc.firstChild;
74
75                 $("#DAname").text(deploymentArtifactName);
76
77                 $("#DAArtifactType").text(daArtifactTypeName);
78                 addHref($("#DAArtifactType"), "artifacttypes", "artifactType", da);
79
80                 var at = $("#DAArtifactTemplate");
81                 if (daArtifactTemplateName != "") {
82                         at.text(daArtifactTemplateName);
83                         addHref(at, "artifacttemplates", "artifactRef", da);
84                 } else {
85                         at.text("No template associated");
86                         at.removeAttr("href");
87                 }
88
89                 $("#DAXML").val(xml);
90
91                 $("#DeploymentArtifactInfo").modal("show");
92         });
93 }
94
95 /**
96  * Adds the given data to the deployment artifacts table of the currently active node template
97  *
98  * @param xmlAsDOM XML DOM document, TDeploymentArtifact. Produced by org.eclipse.winery.resources.artifacts.GenericArtifactsResource.onPost(String, String, String, String, String, String, String, String)
99  * @param xmlAsString
100  */
101 function addDeploymentArtifact(xmlAsDOM, xmlAsString) {
102         var da = xmlAsDOM.firstChild;
103         var daName = da.getAttribute("name");
104
105         // we do NOT extract artifactType / artifactTemplate from the XML, but use the user input
106         // showDeploymentArtifactInformation will extract its data directly from the XML without querying some input at the other HTML elements
107         var daArtifactTemplateName = $("#artifactTemplateName").val();
108         var daArtifactTypeName = $("#artifactType option:selected").text();
109
110         // add information to node template shape
111         var daData = {
112                 nodeTemplateId : currentlySelectedNodeTemplate,
113                 name : daName,
114                 xml : xmlAsString,
115                 artifactTypeName: daArtifactTypeName
116         };
117         if (daArtifactTemplateName != "") {
118                 daData.artifactTemplateName = daArtifactTemplateName;
119         }
120         addDeploymentArtifactInfoToNodeTemplate(daData);
121 }
122
123 function addDeploymentArtifactInfoToNodeTemplate(daData) {
124         require(["tmpl"], function(tmpl){
125                 var data = tmpl("tmpl-deploymentArtifact", daData);
126                 var element = $("#" + currentlySelectedNodeTemplate).children(".deploymentArtifactsContainer").children(".content").children(".addDA:first");
127                 element.before(data);
128         });
129 }
130
131 /**
132  * This function directly accesses the fields of the dialog, because the return value of the server is XML and we do not want to parse XML
133  *
134  * @param artifactInfo = {name, interfaceName (may be undefined), operationName  (may be undefined), artifactTemplate (QName, may be undefined), artifactType}
135  */
136 function artifactAddedSuccessfully(artifactInfo) {
137         var typeNsAndId = getNamespaceAndLocalNameFromQName(artifactInfo.artifactType);
138         var artifactTemplateNSAndId;
139         if (artifactInfo.artifactTemplate) {
140                 artifactTemplateNSAndId = getNamespaceAndLocalNameFromQName(artifactInfo.artifactTemplate);
141         } else {
142                 artifactTemplateNSAndId = undefined;
143         }
144
145         var daData = {
146                 nodeTemplateId : currentlySelectedNodeTemplate,
147                 name : artifactInfo.name,
148                 artifactTypeName: typeNsAndId.localname,
149                 artifactTypeNSAndId: typeNsAndId,
150                 artifactTemplateName: artifactInfo.artifactTemplateName,
151                 artifactTemplateNSAndId: artifactTemplateNSAndId
152         };
153         require(["tmpl"], function(tmpl){
154                 daData.xml = tmpl("tmpl-deploymentArtifactXML", daData);
155                 addDeploymentArtifactInfoToNodeTemplate(daData);
156         });
157 }
158
159 // variables used for creation of deployment artifacts
160 var artifactTemplateAutoCreationEnabled = true;
161 var syncDAnameWithATname;
162
163 // introduced by the handling of deployment and implementation artifacts
164 // holds the ID only (!)
165 var currentlySelectedNodeTemplate;
166
167 /**
168  * FIXME: this function is not updated to the the new dialog design and not included any more
169  *
170  * It should be used if the checkbox for at creation changes its checked status or if the at name is not valid
171  *
172  */
173 function updateArtifactTemplateCreationEnablement(value) {
174         // remove field highlights
175         // (currently, no intelligent removal and addition is made)
176         $("#artifactName").removeClass("highlight");
177         $("#artifactTemplateName").removeClass("highlight");
178
179         if (value) {
180                 // enable it
181                 artifactTemplateAutoCreationEnabled = true;
182                 $("#artifactTemplateName").removeAttr("disabled");
183                 $("#artifactTemplateNS").removeAttr("disabled");
184                 $("#createWithoutFilesBtn").attr("disabled", "disabled");
185                 $("#createWithFilesBtn").removeAttr("disabled");
186         } else {
187                 // disable it
188                 artifactTemplateAutoCreationEnabled = false;
189                 $("#artifactTemplateName").attr("disabled", "disabled");
190                 $("#artifactTemplateNS").attr("disabled", "disabled");
191                 $("#createWithoutFilesBtn").removeAttr("disabled");
192                 $("#createWithFilesBtn").attr("disabled", "disabled");
193         }
194 }
195
196 function isShownNodeTemplateShapeChangeBoxes(shape) {
197         return (shape.find(".endpointContainer").is(":visible"));
198 }
199
200 /**
201  * @param shape jQuery object
202  */
203 function showNodeTemplateShapeChangeBoxes(shape) {
204         shape.find(".addDA").show();
205         shape.children(".endpointContainer").show();
206         shape.find(".addnewreqorcap").show();
207         shape.find(".addnewpolicy").show();
208 }
209
210 /**
211  * @param shape jQuery object
212  */
213 function hideNodeTemplateShapeChangeBoxes(shape) {
214         shape.find(".addDA").hide();
215         shape.children(".endpointContainer").hide();
216         shape.find(".addnewreqorcap").hide();
217         shape.find(".addnewpolicy").hide();
218 }
219
220 // indicates if a connection is currently drawn
221 // used to decide whether the node template boxes should be displayed
222 var isInConnectionMode = false;
223
224 function wineryMoveSelectedNodeTemplateShapes(dX, dY) {
225         var shapes = $("div.NodeTemplateShape.selected");
226         hideNodeTemplateShapeChangeBoxes(shapes);
227         shapes.each(function(i, nodeTemplate) {
228                 nodeTemplate = $(nodeTemplate);
229                 var offset = nodeTemplate.offset();
230                 offset.left += dX;
231                 offset.top += dY;
232                 nodeTemplate.offset(offset);
233         });
234         jsPlumb.repaint(shapes);
235 }
236
237
238 /**
239  * Simple eventing framework
240  *
241  * use
242  * winery.events.register(name, function) to register on an event
243  * and
244  * winery.events.fire(name) to fire all registered functions
245  */
246
247 winery = {};
248 winery.events = {
249         _events : {},
250
251         /**
252          * Registers a function
253          *
254          * @return the registered function
255          */
256         register : function(eventName, f) {
257                 if (!winery.events._events[eventName]) {
258                         winery.events._events[eventName] = {};
259                 }
260                 winery.events._events[eventName][f] = f;
261                 return f;
262         },
263
264         /**
265          * Fires all functions associated with the given event name
266          */
267         fire : function(eventName) {
268                 if (winery.events._events[eventName]) {
269                         $.each(winery.events._events[eventName], function(index, value) {
270                                 value();
271                         });
272                 }
273                 return true;
274         }
275 };
276
277 /**
278  * Determines whether a key combo is allowed.
279  *
280  * For instance, when a modal dialog is opened or a input is selected, DEL should not delete node template shapes
281  */
282 function keyComboAllowed() {
283         return ((!$(document.activeElement).is("input")) && ($("div.modal:visible").size() == 0));
284 }
285
286 function keyComboAllowedAndNodeTemplatesSelected() {
287         return (keyComboAllowed() && ($("div.NodeTemplateShape.selected").size() != 0));
288 }
289
290
291
292
293 /* list of event names */
294 winery.events.name = {};
295 winery.events.name.command = {};
296
297 winery.events.name.SELECTION_CHANGED = "selectionchanged";
298 winery.events.name.command.SELECT_ALL_NODETEMPLATES = "selectAllNodeTemplates";
299 winery.events.name.command.UNSELECT_ALL_NODETEMPLATES = "unselectAllNodeTemplates";
300 winery.events.name.command.DELETE_SELECTION = "deleteSelection";
301
302 winery.events.name.command.MOVE_DOWN = "moveDown";
303 winery.events.name.command.MOVE_UP = "moveUp";
304 winery.events.name.command.MOVE_LEFT = "moveLeft";
305 winery.events.name.command.MOVE_RIGHT = "moveRight";
306
307 winery.events.name.command.SAVE = "save";
308