Add winery source code
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.repository / src / main / webapp / WEB-INF / tags / topologyTemplateRenderer.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  *    Pascal Hirmer - skeletton for topology rendering
12  *    Oliver Kopp - converted to .tag and integrated in the repository
13  *******************************************************************************/
14 --%>
15 <%@tag description="Renders a toplogytemplate. This tag is used to render a topology template readonly. The topoology modeler does the rendering on itself." pageEncoding="UTF-8" %>
16
17 <%@tag import="java.lang.Math"%>
18 <%@tag import="java.util.ArrayList"%>
19 <%@tag import="java.util.Collection"%>
20 <%@tag import="java.util.Map"%>
21 <%@tag import="java.util.HashMap"%>
22 <%@tag import="java.util.UUID"%>
23 <%@tag import="javax.xml.namespace.QName"%>
24 <%@tag import="org.eclipse.winery.common.ModelUtilities"%>
25 <%@tag import="org.eclipse.winery.model.tosca.TEntityTemplate"%>
26 <%@tag import="org.eclipse.winery.model.tosca.TNodeTemplate"%>
27 <%@tag import="org.eclipse.winery.model.tosca.TNodeType"%>
28 <%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate"%>
29 <%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate.SourceElement"%>
30 <%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate.TargetElement"%>
31 <%@tag import="org.eclipse.winery.model.tosca.TRelationshipType"%>
32 <%@tag import="org.eclipse.winery.model.tosca.TTopologyTemplate"%>
33 <%@tag import="org.eclipse.winery.repository.Utils"%>
34
35 <%@attribute name="topology" required="true" description="the topology template to be rendered" type="org.eclipse.winery.model.tosca.TTopologyTemplate" %>
36 <%@attribute name="repositoryURL" required="true" %>
37 <%@attribute name="client" required="true" type="org.eclipse.winery.common.interfaces.IWineryRepository" %>
38 <%@attribute name="fullscreen" required="false" type="java.lang.Boolean" %>
39 <%@attribute name="additonalCSS" required="false"%>
40 <%@attribute name="autoLayoutOnLoad" required="false" type="java.lang.Boolean" %>
41
42 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
43 <%@taglib prefix="tmpl" tagdir="/WEB-INF/tags/common/templates" %>
44 <%@taglib prefix="nt"   tagdir="/WEB-INF/tags/common/templates/nodetemplates" %>
45 <%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%>
46
47 <%-- required for vShowError --%>
48 <script type="text/javascript" src="${w:topologyModelerURI()}/components/pnotify/jquery.pnotify.js"></script>
49 <script type="text/javascript" src="${w:topologyModelerURI()}/js/winery-common.js"></script>
50
51 <%-- required for vShowError --%>
52 <link type="text/css" href="${w:topologyModelerURI()}/components/pnotify/jquery.pnotify.default.css" media="all" rel="stylesheet" />
53 <link type="text/css" href="${w:topologyModelerURI()}/components/pnotify/jquery.pnotify.default.icons.css" media="all" rel="stylesheet" />
54
55 <%-- winery-common.css also contains definitions for properties --%>
56 <link type="text/css" href="${w:topologyModelerURI()}/css/winery-common.css" rel="stylesheet" />
57 <link type="text/css" href="${w:topologyModelerURI()}/css/topologytemplatecontent.css" rel="stylesheet" />
58 <link rel="stylesheet" href="${pageContext.request.contextPath}/css/topologyTemplateRenderer.css" />
59 <c:if test="${not empty fullscreen}"><link rel="stylesheet" href="${pageContext.request.contextPath}/css/topologyTemplateRendererFullscreen.css" /></c:if>
60 <c:if test="${not empty additonalCSS}"><link rel="stylesheet" href="${additonalCSS}" /></c:if>
61
62 <%
63         Collection<TRelationshipType> relationshipTypes = client.getAllTypes(TRelationshipType.class);
64
65         // quick hack
66         // better would be to collect all types used in the curren topoloy template
67         Collection<TNodeType> nodeTypes = client.getAllTypes(TNodeType.class);
68 %>
69
70 <tmpl:CSSForTypes nodeTypes="<%=nodeTypes%>" relationshipTypes="<%=relationshipTypes%>"/>
71
72 <script>
73 // required by winery-common-topologyrendering
74 if (typeof winery === "undefined") winery = {}
75 if (typeof winery.connections === "undefined") winery.connections = {}
76
77 //enable caching. This disables appending of "?_=xy" at requests
78 jQuery.ajaxSetup({cache:true});
79
80 //configuration for pnotify
81 require(["jquery", "pnotify"], function() {
82         $.pnotify.defaults.styling = "bootstrap3";
83 });
84 </script>
85
86 <%
87         // used for the position of the NodeTemplates
88         int topCounter = 0;
89 %>
90 <script>
91 function doLayout() {
92         var editor = $("#editorArea");
93         var nodeTemplates = editor.find(".NodeTemplateShape");
94         require(["winery-sugiyamaLayouter"], function(layouter) {
95                 layouter.layout(nodeTemplates);
96         });
97 }
98 </script>
99 <div class="topbar">
100         <div class="topbarbuttons">
101                 <button class="btn btn-default" onclick="doLayout();">Layout</button>
102                 <tmpl:toggleButtons />
103         </div>
104 </div>
105 <%-- div #editorArea required for layouter --%>
106 <div id="editorArea">
107 <div id="templateDrawingArea">
108
109 <tmpl:defineCreateConnectorEndpointsFunction relationshipTypes="<%=relationshipTypes%>"/>
110
111 <%
112         // can be used later to call a doLayout()
113         boolean somethingWithoutPosition = false;
114
115         Collection<TRelationshipTemplate> relationshipTemplates = new ArrayList<TRelationshipTemplate>();
116         Collection<TNodeTemplate> nodeTemplates = new ArrayList<TNodeTemplate>();
117
118         // the minimum x/y coordinates.
119         // used to move the content to the top left corner
120         int minTop = Integer.MAX_VALUE;
121         int minLeft = Integer.MAX_VALUE;
122
123         for (TEntityTemplate entity: topology.getNodeTemplateOrRelationshipTemplate()) {
124                 if (entity instanceof TNodeTemplate) {
125                         TNodeTemplate nodeTemplate = (TNodeTemplate) entity;
126                         nodeTemplates.add(nodeTemplate);
127
128                         // determine minTop and minLeft
129                         String top = ModelUtilities.getTop(nodeTemplate);
130                         if (top != null) {
131                                 int intTop = Utils.convertStringToInt(top);
132                                 if (intTop != 0) {
133                                         minTop = Math.min(minTop, intTop);
134                                 }
135                         }
136
137                         String left = ModelUtilities.getLeft(nodeTemplate);
138                         if (left != null) {
139                                 int intLeft = Utils.convertStringToInt(left);
140                                 if (intLeft != 0) {
141                                         minLeft = Math.min(minLeft, intLeft);
142                                 }
143                         }
144
145                 } else {
146                         assert(entity instanceof TRelationshipTemplate);
147                         relationshipTemplates.add((TRelationshipTemplate) entity);
148                 }
149         }
150
151         for (TNodeTemplate nodeTemplate: nodeTemplates) {
152                 // assuming the topology can be displayed as a stack, else call doLayout() afterwards
153                 topCounter = topCounter + 150;
154
155                 String left = ModelUtilities.getLeft(nodeTemplate);
156                 if (left == null) {
157                         left = "0";
158                         somethingWithoutPosition = true;
159                 } else {
160                         // calulate offset
161                         // we could hash the coordinate in the loop before
162                         // but that would obfuscate the code and currently, we don't have speed issues here
163                         left = Integer.toString(Utils.convertStringToInt(left) - minLeft);
164                 }
165                 String top = ModelUtilities.getTop(nodeTemplate);
166                 if (top == null) {
167                         top = Integer.toString(topCounter);
168                         somethingWithoutPosition = true;
169                 } else {
170                         // calulate offset
171                         top = Integer.toString(Utils.convertStringToInt(top) - minTop);
172                 }
173 %>
174                 <nt:nodeTemplateRenderer top="<%=top%>" left="<%=left%>" nodeTemplate="<%=nodeTemplate%>" repositoryURL="${repositoryURL}" client="<%=client%>" relationshipTypes="<%=relationshipTypes%>" topologyModelerURI="${w:topologyModelerURI()}/" />
175 <%
176         }
177         if (somethingWithoutPosition) {
178                 autoLayoutOnLoad = true;
179         }
180 %>
181
182 <script>
183 function onDoneRendering() {
184         <c:if test="${autoLayoutOnLoad}">
185         doLayout();
186         </c:if>
187
188         // copied from index.jsp -> togglePrintView
189
190         // move labels 10 px up
191         // we have to do it here as jsPlumb currently paints the label on the line instead of above of it
192         // See https://groups.google.com/d/msg/jsplumb/zdyAdWcRta0/K6F2MrHBH1AJ
193         $(".relationshipTypeLabel").each(function(i, e) {
194                 var pos = $(e).offset();
195                 pos.top = pos.top - 10;
196                 $(e).offset(pos);
197         });
198
199         // The user can pass an additional script to the topologyTemplateResource via the script query parameter
200         // In that script, he can define the function wineryViewExternalScriptOnLoad which is called here
201         if (typeof wineryViewExternalScriptOnLoad === "function") {
202                 wineryViewExternalScriptOnLoad();
203         }
204 }
205 </script>
206 <tmpl:registerConnectionTypesAndConnectNodeTemplates repositoryURL="${repositoryURL}" relationshipTypes="<%=relationshipTypes%>" relationshipTemplates="<%=relationshipTemplates%>" ondone="onDoneRendering();" readOnly="true"/>
207 </div>
208 </div>