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
11 * Oliver Kopp - initial API and implementation and/or initial documentation
12 *******************************************************************************/
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"%>
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"%>
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"%>
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" %>
33 // TODO: check if allArtifactTypes is empty -> then an error message should be shown. Alternative: Add "Manage" button next to "artifact types"
35 function addArtifact() {
36 if (highlightRequiredFields()) {
37 vShowError("Please fill out required fields.");
41 var artifactTemplateCreationMode = $("input[name='artifactTemplateCreation']:checked").val();
42 var autoCreateArtifactTemplate = (artifactTemplateCreationMode=="createArtifactTemplate");
44 if (autoCreateArtifactTemplate && ($("#artifactTemplateNameIsValid:visible").hasClass("invalid"))) {
45 vShowError("Please ensure that the artifact template QName is valid.");
50 /* begin: form serialization */
52 var theForm = $('#add${name}ArtifactForm');
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 :)
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"];
66 vShowError("Code not consistent with UI");
70 disabledFields.forEach(function(element) {
71 $("#"+element).attr("disabled", "disabled");
73 $("input[name='artifactTemplateCreation']").attr("disabled", "disabled");
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";
82 // enable fields again
83 disabledFields.forEach(function(element) {
84 $("#"+element).removeAttr("disabled");
86 $("input[name='artifactTemplateCreation']").removeAttr("disabled");
88 /* end: form serialization */
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
98 var pos = data.indexOf("operationName=");
99 var posNextParam = data.indexOf("&", pos);
100 data = data.substr(0, pos) + "operationName=" + operationName + data.substr(posNextParam);
104 // We assume that the artifact type exists
105 // i.e., that it was not deleted during loading of the dialog
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
117 error: function(jqXHR, textStatus, errorThrown) {
118 vShowAJAXError("Could not create ${name} Artifact", jqXHR, errorThrown);
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
124 name: $("#artifactName").val(),
125 interfaceName: $("#interfaceName").val(),
126 operationName: $("#operationName option:selected").text()
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);
150 error: function(jqXHR, textStatus, errorThrown) {
151 vShowAJAXError("Could not get type of artifact template", jqXHR, errorThrown);
154 success: function(resData, textStatus, jqXHR) {
155 // QName is directly returned
156 artifactInfo.artifactType = resData;
161 vShowError("Code not consistent with UI");
163 // now, artifactInfo is filled completly
165 // the function can be called
166 ${onSuccessfulArtifactCreationFunction}(artifactInfo);
168 $('#add${name}ArtifactDiag').modal('hide');
169 vShowSuccess("Artifact added successfully");
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');
186 <c:if test="${not isDeploymentArtifact}">
187 <script type="text/javascript" src="${pageContext.request.contextPath}/js/nextselect.js"></script>
189 var dependendSelects = {"#interfaceName": "#operationName"};
190 var interfaceOpData = {
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
200 <c:forEach var="u" varStatus="loop" items="${t.operationsResouce.listOfAllEntityIdsAsList}">
201 "${t.name}:${u}"<c:if test="${!loop.last}">,</c:if>
206 <c:forEach var="t" varStatus="outerLoop" items="${interfacesOfAssociatedType}">
207 <c:forEach var="u" varStatus="innerLoop" items="${t.operationsResouce.listOfAllEntityIdsAsList}">
210 }<c:if test="${!innerLoop.last or !outerLoop.last}">,</c:if>
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">×</button>
222 <h4 class="modal-title">Add ${name} Artifact</h4>
224 <div class="modal-body">
225 <form id="add${name}ArtifactForm" enctype="multipart/form-data">
228 <div class="form-group">
230 <input class="form-control" name="artifactName" id="artifactName" type="text" required="required" autocomplete="on" />
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>
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 --%>
252 <h4>Artifact Template Creation</h4>
255 <input type="radio" name="artifactTemplateCreation" value="createArtifactTemplate" checked="checked" id="createArtifactTemplateInput">Create Artifact Template</input>
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>
261 <input type="radio" name="artifactTemplateCreation" value="linkArtifactTemplate">Link Artifact Template</input>
263 <p class="help-block">Check if you want to reuse existing files.</p>
267 <input type="radio" name="artifactTemplateCreation" value="skipArtifactTemplate">Do not create an artifact template</input>
269 <p class="help-block">Check if you want to point to an image library.</p>
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>
284 <fup:artifacttemplateselection allNamespaces="${allNamespaces}" repositoryURL="${repositoryURL}" defaultNSForArtifactTemplate="${defaultNSForArtifactTemplate}"/>
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%">
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>
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>
309 function openAdd${name}ArtifactDiag() {
311 url: "${repositoryURL}/artifacttemplates/",
314 error: function(jqXHR, textStatus, errorThrown) {
315 vShowAJAXError("Could not fetch available artifact templates", jqXHR, errorThrown);
317 success: function(data, textStatus, jqXHR) {
318 var select = $("#artifactTemplateToLink");
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);
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));
331 select.trigger("change");
332 $('#add${name}ArtifactDiag').modal('show');
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();
343 $("#artifactType").select2();
344 $("#artifactTemplateToLink").select2();
347 requirejs(['tmpl', 'jquery.ui.widget', 'jquery.fileupload', 'jquery.fileupload-ui'], function() {
348 $('#fileupload').fileupload({
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();
373 vShowError("Code not consistent with UI");
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");
384 $("#artifactName").typing({
385 start: function(event, $elem) {
386 if (syncDAnameWithATname) {
387 require(["artifacttemplateselection"], function(ats) {
388 ats.flagArtifactTemplateNameAsUpdating();
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();
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);
407 .on("focus", function() {
408 syncDAnameWithATname = ($("#artifactTemplateName").is(":visible")) && (this.value == $("#artifactTemplateName").val());
411 $("#artifactTemplateToLink").on("change", function(evt) {
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);
425 <%-- file uploading part --%>
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">×</button>
432 <h4 class="modal-title">Add files to artifact template <a id="artifactTemplateNameAtUploadFiles"></a></h4>
434 <div class="modal-body">
435 <fup:jquery-file-upload-full loadexistingfiles="false"></fup:jquery-file-upload-full>
437 <div class="modal-footer">
438 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
440 <!-- addFilesToArtifactTemplate -->