Merge "Fix build errors in autorelease full clean build"
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.topologymodeler / src / main / webapp / WEB-INF / tags / common / artifactcreationdialog.tag
1 <%--
2 /*******************************************************************************
3  * Copyright (c) 2013 University of Stuttgart.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * and the Apache License 2.0 which both accompany this distribution,
7  * and are available at http://www.eclipse.org/legal/epl-v10.html
8  * and http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Contributors:
11  *    Oliver Kopp - initial API and implementation and/or initial documentation
12  *******************************************************************************/
13 --%>
14 <%@tag description="Dialog for adding an implementation / deployment artifact" pageEncoding="UTF-8"%>
15 <%@taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>
16 <%@taglib prefix="fup" tagdir="/WEB-INF/tags/common"%>
17
18 <%@attribute name="name" required="true" description="Implementation | Deployment"%>
19 <%@attribute name="repositoryURL" required="true" description="the URL of Winery's repository"%>
20 <%@attribute name="onSuccessfulArtifactCreationFunction" required="true" description="javascript code to be executed when the artifact has been successfully created. Parameter: artifactInfo"%>
21 <%@attribute name="allArtifactTypes" required="true" type="java.util.Collection" description="All available artifact types"%>
22 <%@attribute name="allNamespaces" required="true" type="java.util.Collection" description="All known namespaces"%>
23 <%@attribute name="defaultNSForArtifactTemplate" required="true" description="the default namespace of the artifact template"%>
24
25 <%-- either URL or a function to be called for addition --%>
26 <%@attribute name="URL" required="true" description="the URL of the artifact collection. May also be a function returning the correct URL (used at the topology modeler). I.e., it is an expression being evaluated"%>
27
28 <%@attribute name="isDeploymentArtifact" required="true" type="java.lang.Boolean" description="Is this dialog used to create deployment artifacts?"%>
29 <%-- required if implementation artifact --%>
30 <%@attribute name="interfacesOfAssociatedType" type="java.util.List" %>
31
32 <script>
33 // TODO: check if allArtifactTypes is empty -> then an error message should be shown. Alternative: Add "Manage" button next to "artifact types"
34
35 function addArtifact() {
36         if (highlightRequiredFields()) {
37                 vShowError("Please fill out required fields.");
38                 return;
39         }
40
41         var artifactTemplateCreationMode = $("input[name='artifactTemplateCreation']:checked").val();
42         var autoCreateArtifactTemplate = (artifactTemplateCreationMode=="createArtifactTemplate");
43
44         if (autoCreateArtifactTemplate && ($("#artifactTemplateNameIsValid:visible").hasClass("invalid"))) {
45                 vShowError("Please ensure that the artifact template QName is valid.");
46                 return;
47         }
48
49
50         /* begin: form serialization */
51
52         var theForm = $('#add${name}ArtifactForm');
53
54         // do not serialze hidden fields
55         // theForm.find("select:hidden,input:hidden").attr("disabled", "disabled");
56         // Because we use "select2", the user-visible select fields are divs. The "real" selects are hidden.
57         // Therefore, we disable fields manually :)
58         var disabledFields;
59         if (artifactTemplateCreationMode == "skipArtifactTemplate") {
60                 disabledFields = ["artifactTemplateName", "artifactTemplateNS", "artifactTemplateToLink"];
61         } else if (artifactTemplateCreationMode == "createArtifactTemplate") {
62                 disabledFields = ["artifactTemplateToLink"];
63         } else if (artifactTemplateCreationMode == "linkArtifactTemplate") {
64                 disabledFields = ["artifactTemplateName",  "artifactTemplateNS", "artifactType"];
65         } else {
66                 vShowError("Code not consistent with UI");
67         }
68
69         // make a clean form
70         disabledFields.forEach(function(element) {
71                 $("#"+element).attr("disabled", "disabled");
72         });
73         $("input[name='artifactTemplateCreation']").attr("disabled", "disabled");
74
75         // do not serialize choice directly, but ...
76         // ... append "autoCreateArtifactTemplate=true" in case the artifact template should be auto created
77         var data = theForm.serialize();
78         if (autoCreateArtifactTemplate) {
79                 data = data + "&autoCreateArtifactTemplate=true";
80         }
81
82         // enable fields again
83         disabledFields.forEach(function(element) {
84                 $("#"+element).removeAttr("disabled");
85         });
86         $("input[name='artifactTemplateCreation']").removeAttr("disabled");
87
88         /* end: form serialization */
89
90         <c:if test="${not isDeploymentArtifact}">
91         var operationVal = $("#operationName").val();
92         if ((operationVal) && (operationVal != "")) {
93                 var operationName = $("#operationName option:selected").text();
94                 // The operationname is prefixed with the namespace, because of "nextselect"
95                 // we have to undo that effect.
96                 // Therefore, we replace the complete operationName parameter
97
98                 var pos = data.indexOf("operationName=");
99                 var posNextParam = data.indexOf("&", pos);
100                 data = data.substr(0, pos) + "operationName=" + operationName + data.substr(posNextParam);
101         }
102         </c:if>
103
104         // We assume that the artifact type exists
105         // i.e., that it was not deleted during loading of the dialog
106
107         // The deployment artifact resource allows auto creation of the artifact template
108         // We do not need to do that manually using a separate POST call
109         // TODO: In a future version, this might be better have a clean way to create additional content for an artifact template
110
111         // do the addCall
112         $.ajax({
113                 url: ${URL},
114                 type: "POST",
115                 async: false,
116                 "data": data,
117                 error: function(jqXHR, textStatus, errorThrown) {
118                         vShowAJAXError("Could not create ${name} Artifact", jqXHR, errorThrown);
119                 },
120                 success: function(data, textStatus, jqXHR) {
121                         // prepare data for onSuccessfulArtifactCreationFunction
122                         // even though interaceName and operationName do not exist at DA, accessing it via jQuery works: then "undefined" is returned, which is OK
123                         var artifactInfo = {
124                                 name: $("#artifactName").val(),
125                                 interfaceName: $("#interfaceName").val(),
126                                 operationName: $("#operationName option:selected").text()
127                         };
128                         if (artifactTemplateCreationMode == "skipArtifactTemplate") {
129                                 // artifactTemplate remains unset as there is not artifactTemplate to be created
130                                 artifactInfo.artifactType = $("#artifactType").val();
131                         } else if (artifactTemplateCreationMode == "createArtifactTemplate") {
132                                 artifactInfo.artifactTemplateName = $("#artifactTemplateName").val();
133                                 // FIXME: This is a quick hack - the name could have been changed at the server as it might contain invalid characters for an id
134                                 // In other words, $("#artifactTemplateName").val() might not be the localName of the artifactTemplate
135                                 artifactInfo.artifactTemplate = "{" + $("#artifactTemplateNS").val() + "}" + $("#artifactTemplateName").val();
136                                 artifactInfo.artifactType = $("#artifactType").val();
137                         } else if (artifactTemplateCreationMode == "linkArtifactTemplate") {
138                                 artifactInfo.artifactTemplateName = $("#artifactTemplateToLink option:selected").text();
139                                 artifactInfo.artifactTemplate = $("#artifactTemplateToLink").val();
140                                 // artifact type is a mandantory field
141                                 // we have to ask the artifact template for the QName of its type and then use this data
142                                 require(["winery-support-common"], function(wsc) {
143                                         var nsAndId = wsc.getNamespaceAndLocalNameFromQName(artifactInfo.artifactTemplate);
144                                         var url = makeArtifactTemplateURL("${repositoryURL}", nsAndId.namespace, nsAndId.localname);
145                                         $.ajax({
146                                                 type: "GET",
147                                                 async: false,
148                                                 url: url + "?type",
149                                                 dataType: "text",
150                                                 error: function(jqXHR, textStatus, errorThrown) {
151                                                         vShowAJAXError("Could not get type of artifact template", jqXHR, errorThrown);
152                                                         return;
153                                                 },
154                                                 success: function(resData, textStatus, jqXHR) {
155                                                         // QName is directly returned
156                                                         artifactInfo.artifactType = resData;
157                                                 }
158                                         });
159                                 });
160                         } else {
161                                 vShowError("Code not consistent with UI");
162                         }
163                         // now, artifactInfo is filled completly
164
165                         // the function can be called
166                         ${onSuccessfulArtifactCreationFunction}(artifactInfo);
167
168                         $('#add${name}ArtifactDiag').modal('hide');
169                         vShowSuccess("Artifact added successfully");
170
171                         if (autoCreateArtifactTemplate) {
172                                 var aritfactTemplateNS = $("#artifactTemplateNS").val();
173                                 var artifactTemplateName = $("#artifactTemplateName").val();
174                                 var artifactTemplateURL = makeArtifactTemplateURL("${repositoryURL}", aritfactTemplateNS, artifactTemplateName);
175                                 $("#artifactTemplateNameAtUploadFiles").text(artifactTemplateName).attr("href", artifactTemplateURL);
176                                 var url = artifactTemplateURL + "files/";
177                                 $('#fileupload').fileupload('option', 'url', url);
178                                 $("#addFilesToArtifactTemplate").modal('show');
179                         }
180                 }
181         });
182
183 }
184 </script>
185
186 <c:if test="${not isDeploymentArtifact}">
187         <script type="text/javascript" src="${pageContext.request.contextPath}/js/nextselect.js"></script>
188         <script>
189                 var dependendSelects = {"#interfaceName": "#operationName"};
190                 var interfaceOpData = {
191                         "": {
192                                 label : "(none)",
193                                 "options" : []
194                         }<c:if test="${not empty interfacesOfAssociatedType}">,</c:if>
195                         <c:forEach var="t" items="${interfacesOfAssociatedType}">
196                                 // no label necessary as this list is pre-filled
197                                 "${t.name}": {
198                                         "options" : [
199                                                 "",
200                                                 <c:forEach var="u" varStatus="loop" items="${t.operationsResouce.listOfAllEntityIdsAsList}">
201                                                         "${t.name}:${u}"<c:if test="${!loop.last}">,</c:if>
202                                                 </c:forEach>
203                                         ]
204                                 },
205                         </c:forEach>
206                         <c:forEach var="t" varStatus="outerLoop" items="${interfacesOfAssociatedType}">
207                                 <c:forEach var="u" varStatus="innerLoop" items="${t.operationsResouce.listOfAllEntityIdsAsList}">
208                                 "${t.name}:${u}" : {
209                                         "label": "${u}"
210                                 }<c:if test="${!innerLoop.last or !outerLoop.last}">,</c:if>
211                                 </c:forEach>
212                         </c:forEach>
213                 };
214         </script>
215 </c:if>
216
217 <div class="modal fade" id="add${name}ArtifactDiag">
218         <div class="modal-dialog">
219                 <div class="modal-content">
220                         <div class="modal-header">
221                                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
222                                 <h4 class="modal-title">Add ${name} Artifact</h4>
223                         </div>
224                         <div class="modal-body">
225                                 <form id="add${name}ArtifactForm" enctype="multipart/form-data">
226                                         <fieldset>
227
228                                                 <div class="form-group">
229                                                         <label>Name</label>
230                                                         <input class="form-control" name="artifactName" id="artifactName" type="text" required="required" autocomplete="on" />
231                                                 </div>
232
233                                                 <c:if test="${not isDeploymentArtifact}">
234                                                         <div class="form-group">
235                                                                 <label for="interfaceName">Interface Name</label>
236                                                                 <select name="interfaceName" id="interfaceName" class="form-control" onchange="updateListContent(this.value, '#operationName', dependendSelects, interfaceOpData);">
237                                                                         <option value="" selected="selected">(none)</option>
238                                                                         <c:forEach var="t" items="${interfacesOfAssociatedType}">
239                                                                                 <option value="${t.name}">${t.name}</option>
240                                                                         </c:forEach>
241                                                                 </select>
242                                                         </div>
243
244                                                         <div class="form-group">
245                                                                 <label for="operationName">Operation Name</label>
246                                                                 <select name="operationName" id="operationName" class="form-control">
247                                                                         <%-- options filled by updateListContent defined by nextselect.js --%>
248                                                                 </select>
249                                                         </div>
250                                                 </c:if>
251
252                                                 <h4>Artifact Template Creation</h4>
253                                                 <div class="radio">
254                                                         <label>
255                                                                 <input type="radio" name="artifactTemplateCreation" value="createArtifactTemplate" checked="checked" id="createArtifactTemplateInput">Create Artifact Template</input>
256                                                         </label>
257                                                         <p class="help-block">Check if you want to upload <strong>new</strong> files, you do not want to reuse existing files and you do not point to an image library.</p>
258                                                 </div>
259                                                 <div class="radio">
260                                                         <label>
261                                                                 <input type="radio" name="artifactTemplateCreation" value="linkArtifactTemplate">Link Artifact Template</input>
262                                                         </label>
263                                                         <p class="help-block">Check if you want to reuse existing files.</p>
264                                                 </div>
265                                                 <div class="radio">
266                                                         <label>
267                                                                 <input type="radio" name="artifactTemplateCreation" value="skipArtifactTemplate">Do not create an artifact template</input>
268                                                         </label>
269                                                         <p class="help-block">Check if you want to point to an image library.</p>
270                                                 </div>
271                                         </fieldset>
272                                         <fieldset id="artifactTypeFieldset">
273                                                 <div class="form-group" id="artifactTypeDiv">
274                                                         <label for="artifactType">Artifact Type</label>
275                                                         <select name="artifactType" class="form-control" id="artifactType">
276                                                                 <c:forEach var="t" items="${allArtifactTypes}">
277                                                                         <option value="${t.toString()}">${t.localPart}</option>
278                                                                 </c:forEach>
279                                                         </select>
280                                                 </div>
281                                         </fieldset>
282                                         <fieldset>
283
284                                                 <fup:artifacttemplateselection allNamespaces="${allNamespaces}" repositoryURL="${repositoryURL}" defaultNSForArtifactTemplate="${defaultNSForArtifactTemplate}"/>
285
286                                                 <div id="linkArtifactTemplate" class="form-group" style="display:none;">
287                                                         <label for="divArtifactTemplateToLink">Artifact Template</label>
288                                                         <div id="divArtifactTemplateToLink">
289                                                                 <%-- filled by jQuery at openAdd${name}ArtifactDiag() --%>
290                                                                 <select id=artifactTemplateToLink name="artifactTemplate" class="form-control" style="max-width: 90%">
291                                                                 </select>
292                                                                 <%-- URL is changed each time the selection is changed --%>
293                                                                 <a href="#" target="_blank" class="btn btn-info btn-sm" id="viewArtifactTemplateToLink">view</a>
294                                                         </div>
295                                                 </div>
296                                         </fieldset>
297                                 </form>
298                         </div>
299                         <div class="modal-footer">
300                                 <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
301                                 <button type="button" class="btn btn-primary" onclick="addArtifact();">Add</button>
302                         </div>
303                 </div>
304         </div>
305 </div>
306
307
308 <script>
309 function openAdd${name}ArtifactDiag() {
310         $.ajax({
311                 url: "${repositoryURL}/artifacttemplates/",
312                 dataType: "json",
313                 async: false,
314                 error: function(jqXHR, textStatus, errorThrown) {
315                         vShowAJAXError("Could not fetch available artifact templates", jqXHR, errorThrown);
316                 },
317                 success: function(data, textStatus, jqXHR) {
318                         var select = $("#artifactTemplateToLink");
319                         select.empty();
320                         $.each(data, function(index, o) {
321                                 var qname = "{" + this.namespace + "}" + this.id;
322                                 var option = '<option value="' + qname + '">' + this.name + '</option>';
323                                 select.append(option);
324                                 if (index==0) {
325                                         // first element
326                                         // this is the selected element
327                                         // we put it as href to the "view" button
328                                         $("#viewArtifactTemplateToLink").attr("href", makeArtifactTemplateURL("${repositoryURL}", this.namespace, this.id));
329                                 }
330                         });
331                         select.trigger("change");
332                         $('#add${name}ArtifactDiag').modal('show');
333                 }
334         });
335 }
336
337 requirejs(["select2"], function() {
338         $("#interfaceName").select2();
339         <c:if test="${not isDeploymentArtifact}">
340         // the dependend select cannot be a select2 until https://github.com/ivaynberg/select2/issues/1656 is resolved
341         //$("#operationName").select2();
342         </c:if>
343         $("#artifactType").select2();
344         $("#artifactTemplateToLink").select2();
345 });
346
347 requirejs(['tmpl', 'jquery.ui.widget', 'jquery.fileupload', 'jquery.fileupload-ui'], function() {
348         $('#fileupload').fileupload({
349                 "autoUpload": true
350         });
351 });
352
353 $(function(){
354         $("input[name='artifactTemplateCreation']").on("change", function(e) {
355                 var choice = $(e.target).attr("value");
356                 if (choice == "skipArtifactTemplate") {
357                         $(".createArtifactTemplate").hide();
358                         $("#linkArtifactTemplate").hide();
359                         $("#artifactTypeFieldset").removeAttr("disabled");
360                         $("#artifactTypeDiv").show();
361                 } else if (choice == "createArtifactTemplate") {
362                         $(".createArtifactTemplate").show();
363                         $("#linkArtifactTemplate").hide();
364                         $("#artifactTypeFieldset").removeAttr("disabled");
365                         $("#artifactTypeDiv").show();
366                         // one might be copy the template name to the artifact template name (if ($("#artifactTemplateName").val() == ""))
367                 } else if (choice == "linkArtifactTemplate") {
368                         $(".createArtifactTemplate").hide();
369                         $("#linkArtifactTemplate").show();
370                         $("#artifactTypeFieldset").attr("disabled", "disabled");
371                         $("#artifactTypeDiv").hide();
372                 } else {
373                         vShowError("Code not consistent with UI");
374                 };
375         });
376
377         $("#add${name}ArtifactDiag").on('shown.bs.modal', function() {
378                 $(this).find('form')[0].reset();
379                 // createArtifactTemplate is the default seeting for the form
380                 // reset the dialog to this choice
381                 $("#createArtifactTemplateInput").trigger("change");
382         });
383
384         $("#artifactName").typing({
385                 start: function(event, $elem) {
386                         if (syncDAnameWithATname) {
387                                 require(["artifacttemplateselection"], function(ats) {
388                                         ats.flagArtifactTemplateNameAsUpdating();
389                                 });
390                         }
391                 },
392                 stop: function(event, $elem) {
393                         // value is copied at the "change keyup input" event at #artifactName
394                                 require(["artifacttemplateselection"], function(ats) {
395                                         ats.checkArtifactTemplateName();
396                                 });
397                 }
398         });
399
400         $("#artifactName")
401         // tip by http://solicitingfame.com/2011/11/09/jquery-keyup-vs-bind/
402         .bind("change keyup input", function() {
403                 if (syncDAnameWithATname) {
404                         $("#artifactTemplateName").val(this.value);
405                 }
406         })
407         .on("focus", function() {
408                 syncDAnameWithATname = ($("#artifactTemplateName").is(":visible")) && (this.value == $("#artifactTemplateName").val());
409         });
410
411         $("#artifactTemplateToLink").on("change", function(evt) {
412                 if (evt.val) {
413                         // TODO: possibly use makeArtifactTemplateURL("${repositoryURL}", this.namespace, this.id)) here
414                         require(["winery-support-common"], function(w) {
415                                 var fragment = w.getURLFragmentOutOfFullQName(evt.val);
416                                 var url = "${repositoryURL}/artifacttemplates/" + fragment + "/";
417                                 $("#viewArtifactTemplateToLink").attr("href", url);
418                         });
419                 }
420         });
421 });
422 </script>
423
424
425 <%-- file uploading part --%>
426
427 <div class="modal fade" id="addFilesToArtifactTemplate">
428         <div class="modal-dialog">
429                 <div class="modal-content">
430                         <div class="modal-header">
431                                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
432                                 <h4 class="modal-title">Add files to artifact template <a id="artifactTemplateNameAtUploadFiles"></a></h4>
433                         </div>
434                         <div class="modal-body">
435                                 <fup:jquery-file-upload-full loadexistingfiles="false"></fup:jquery-file-upload-full>
436                         </div>
437                         <div class="modal-footer">
438                                 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
439                         </div>
440                 <!-- addFilesToArtifactTemplate -->
441                 </div>
442         </div>
443 </div>