2 /*******************************************************************************
3 * Copyright (c) 2013 Pascal Hirmer.
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 * Pascal Hirmer - initial API and implementation
12 *******************************************************************************/
15 <%@tag language="java" pageEncoding="UTF-8" description="This tag is used to render Topology Templates for selection in a dialog."%>
17 <%-- attributes for the topology selection --%>
18 <%@attribute name="templateURL" type="java.lang.String"%>
19 <%@attribute name="topologyName" type="java.lang.String"%>
20 <%@attribute name="topologyNamespace" type="java.lang.String"%>
21 <%@attribute name="repositoryURL" type="java.lang.String" %>
22 <%@attribute name="solutionTopologies" type="java.util.List<org.eclipse.winery.model.tosca.TTopologyTemplate>"%>
24 <%@tag import="java.io.StringWriter"%>
25 <%@tag import="java.util.HashMap"%>
26 <%@tag import="java.util.Map"%>
27 <%@tag import="java.util.List"%>
28 <%@tag import="java.util.UUID"%>
29 <%@tag import="javax.xml.bind.Marshaller"%>
30 <%@tag import="javax.xml.bind.JAXBContext"%>
31 <%@tag import="javax.xml.bind.JAXBException"%>
32 <%@tag import="javax.xml.namespace.QName"%>
33 <%@tag import="org.eclipse.winery.model.tosca.Definitions"%>
34 <%@tag import="org.eclipse.winery.model.tosca.TEntityTemplate"%>
35 <%@tag import="org.eclipse.winery.model.tosca.TNodeTemplate"%>
36 <%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate"%>
37 <%@tag import="org.eclipse.winery.model.tosca.TRelationshipType"%>
38 <%@tag import="org.eclipse.winery.model.tosca.TServiceTemplate"%>
39 <%@tag import="org.eclipse.winery.model.tosca.TTopologyTemplate"%>
40 <%@tag import="org.eclipse.winery.repository.client.WineryRepositoryClientFactory"%>
41 <%@tag import="org.eclipse.winery.repository.client.IWineryRepositoryClient"%>
42 <%@tag import="org.eclipse.winery.common.Util"%>
44 <%@taglib prefix="ntrq" tagdir="/WEB-INF/tags/common/templates/nodetemplates/reqscaps" %>
45 <%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates"%>
47 <div id="topologyTemplateSelector">
48 <p> There are several possible topology solutions <br> Please select your desired topology: </p>
50 // array to collect the created IDs
53 // save all created connections in an array to be able to detach them after the selection
54 Connections = new Array();
57 // the pixel distance between the displayed NodeTemplates
58 final int NODE_TEMPLATE_DISTANCE = 150;
60 List<TTopologyTemplate> topologyTemplateSelector = solutionTopologies;
63 Map<String, String> idMap;
64 for (TTopologyTemplate choice: topologyTemplateSelector) {
65 Definitions definitions = new Definitions();
66 TServiceTemplate st = new TServiceTemplate();
67 st.setTopologyTemplate(choice);
68 definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().add(st);
69 JAXBContext context = JAXBContext.newInstance(Definitions.class);
70 Marshaller m = context.createMarshaller();
71 StringWriter stringWriter = new StringWriter();
73 m.marshal(definitions, stringWriter);
75 IWineryRepositoryClient client = WineryRepositoryClientFactory.getWineryRepositoryClient();
76 client.addRepository(repositoryURL);
77 String id = "solution" + Integer.toString(i);
79 String sourceId = null;
80 idMap = new HashMap<String, String>();
83 <div id="proposalEditorArea">
84 <div id="proposaldrawingarea">
85 <div id="<%=counter%>">
86 <script> IDs.push("<%=id%>"); </script>
88 for (TEntityTemplate entity: choice.getNodeTemplateOrRelationshipTemplate()) {
90 if (entity instanceof TNodeTemplate) {
91 TNodeTemplate nodeTemplate = (TNodeTemplate) entity;
94 <nt:nodeTemplateRenderer client="<%=client%>" relationshipTypes="<%=client.getAllTypes(TRelationshipType.class)%>" repositoryURL='<%=repositoryURL%>' nodeTemplate="<%=nodeTemplate%>" top="<%=Integer.toString(topCounter)%>" left='<%="0"%>'/>
97 String randomId = UUID.randomUUID().toString();
100 document.getElementById("<%=nodeTemplate.getId()%>").id = "<%=randomId%>";
103 topCounter = topCounter + NODE_TEMPLATE_DISTANCE;
104 idMap.put(nodeTemplate.getId(), randomId);
110 for (TEntityTemplate entity: choice.getNodeTemplateOrRelationshipTemplate()) {
111 if (entity instanceof TRelationshipTemplate) {
112 TRelationshipTemplate connector = (TRelationshipTemplate) entity;
113 sourceId = ((TNodeTemplate) connector.getSourceElement().getRef()).getId();
114 String visualSourceId = idMap.get(sourceId);
115 String targetId = ((TNodeTemplate) connector.getTargetElement().getRef()).getId();
116 String visualTargetId = idMap.get(targetId);
117 QName type = connector.getType();
119 <script type='text/javascript'>
121 require(["winery-common-topologyrendering"], function(wct) {
122 wct.initNodeTemplate(jsPlumb.getSelector(".NodeTemplateShape:not('.hidden')"), true);
123 require(["jsplumb"], function(_jsPlumb) {
124 _jsPlumb.ready(function() {
125 c = _jsPlumb.connect({
126 source:"<%=visualSourceId%>",
127 target:"<%=visualTargetId%>",
134 wct.handleConnectionCreated(c);
144 <input name="<%=id%>" id="<%=id%>" type="checkbox" value='<%=stringWriter.toString()%>' onclick="onClick<%=id%>()"> Save this Topology
147 * Handles a click on the "Save this Topology" checkbox.
149 function onClick<%=id%>() {
150 if (document.getElementById('<%=id%>').checked) {
151 document.getElementById('<%=id + "overwrite"%>').disabled = false;
152 document.getElementById('<%=id + "name"%>').disabled = false;
153 document.getElementById('<%=id + "namespace"%>').disabled = false;
154 document.getElementById('<%=id + "newWindow"%>').disabled = false;
157 document.getElementById('<%=id + "overwrite"%>').disabled = true;
158 document.getElementById('<%=id + "name"%>').disabled = true;
159 document.getElementById('<%=id + "namespace"%>').disabled = true;
160 document.getElementById('<%=id + "newWindow"%>').disabled = true;
164 <input disabled="disabled" name='<%=id + "overwrite"%>' id='<%=id + "overwrite"%>' type="checkbox" onclick='onClick<%=id + "overwrite"%>()'> Overwrite current Topology
167 * Handles a click on the "Overwrite current Topology" checkbox.
169 function onClick<%=id + "overwrite"%>() {
170 if (document.getElementById('<%=id + "overwrite"%>').checked) {
171 document.getElementById('<%=id + "name"%>').disabled = true;
172 document.getElementById('<%=id + "namespace"%>').disabled = true;
173 document.getElementById('<%=id + "newWindow"%>').disabled = true;
175 document.getElementById('<%=id + "name"%>').disabled = false;
176 document.getElementById('<%=id + "namespace"%>').disabled = false;
177 document.getElementById('<%=id + "newWindow"%>').disabled = false;
181 <input disabled="disabled" name='<%=id + "newWindow"%>' id='<%=id + "newWindow"%>' type="checkbox"> Open in new Window <br> <br>
182 <p>Name: <input disabled="disabled" id='<%=id + "name"%>' name='<%=id + "name"%>' value="<%=topologyName%>" type="text" size="30" maxlength="30"> </p>
183 <p>Namespace: <input disabled="disabled" id='<%=id + "namespace"%>' value="<%=topologyNamespace%>" name='<%=id + "namespace"%>' type="text" size="50" maxlength="60"> </p>
189 <button type="button" id="save" class="btn btn-primary btn-default">Save Topologies</button>
191 $('#save').on('click', function() {
193 for (var i = 0; i < IDs.length; i++) {
194 if (document.getElementById(IDs[i]).checked) {
196 var name = document.getElementById(IDs[i] + 'name').value;
197 var namespace = document.getElementById(IDs[i] + 'namespace').value;
198 var overwrite = document.getElementById(IDs[i] + 'overwrite').checked;
199 var openInNewWindow = document.getElementById(IDs[i] + 'newWindow').checked;
201 // check validity of the namespace
202 var validURIregexp = new RegExp("([A-Za-z][A-Za-z0-9+\\-.]*):(?:(//)(?:((?:[A-Za-z0-9\\-._~!$&'()*+,;=:]|%[0-9A-Fa-f]{2})*)@)?((?:\\[(?:(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|::(?:[0-9A-Fa-f]{1,4}:){5}|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)|[Vv][0-9A-Fa-f]+\\.[A-Za-z0-9\\-._~!$&'()*+,;=:]+)\\]|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[A-Za-z0-9\\-._~!$&'()*+,;=]|%[0-9A-Fa-f]{2})*))(?::([0-9]*))?((?:/(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)|/((?:(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:/(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)?)|((?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:/(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)|)(?:\\?((?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*))?(?:\#((?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*))?");
203 if (validURIregexp.test(namespace) || overwrite) {
206 // first create a new service template via AJAX call
207 var dataToSend = "name=" + name + "&namespace=" + namespace;
208 var url = "<%=repositoryURL%>" + "/servicetemplates/";
216 error: function(jqXHR, textStatus, errorThrown) {
217 vShowAJAXError("Could not add Service Template.");
222 // now save the topology template
223 $.post("jsp/topologyCompletion/topologySaver.jsp", {topology: document.getElementById(IDs[i]).value, templateURL: "<%=templateURL%>", repositoryURL: "<%=repositoryURL%>", topologyName: name, topologyNamespace: namespace, overwriteTopology: overwrite},
225 if (openInNewWindow) {
226 // a new topology has been created, open it in a new window
227 var win=window.open('?repositoryURL=' + "<%=repositoryURL%>" + '&ns='+ namespace + '&id=' + name, '_blank');
229 } else if (overwrite) {
231 document.location.reload(true);
234 chooseTopologyDiag.modal("hide");
235 vShowSuccess("Successfully Saved Topologies.")
239 vShowError("Please enter a valid namespace.");