summaryrefslogtreecommitdiffstats
path: root/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates
diff options
context:
space:
mode:
Diffstat (limited to 'winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates')
-rw-r--r--winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/propertiesOfOneNodeTemplate.tag147
-rw-r--r--winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/reqscaps/addorupdatereqorcap.tag248
-rw-r--r--winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/relationshiptemplates/propertiesOfOneRelationshipTemplate.tag179
3 files changed, 574 insertions, 0 deletions
diff --git a/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/propertiesOfOneNodeTemplate.tag b/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/propertiesOfOneNodeTemplate.tag
new file mode 100644
index 0000000..238e34a
--- /dev/null
+++ b/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/propertiesOfOneNodeTemplate.tag
@@ -0,0 +1,147 @@
+<%--
+/*******************************************************************************
+ * Copyright (c) 2012-2013 University of Stuttgart.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ * Uwe Breitenbücher - initial API and implementation and/or initial documentation
+ * Oliver Kopp - improvements to fit updated index.jsp
+ * Yves Schubert - switch to bootstrap 3
+ *******************************************************************************/
+--%>
+
+<%@tag language="java" pageEncoding="UTF-8" description="Renders the properies of one node tempate on the right"%>
+
+<%@attribute name="repositoryURL" required="true" type="java.lang.String" description="The repository URL"%>
+
+<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common" %>
+
+
+<link rel="stylesheet" href="css/propertiesview.css" />
+
+<div id="NTPropertiesView" class="propertiesView" style="display: none;">
+
+ <div id="nodeTemplateInformationSection">
+ <%--
+ If this is layouted strangely, maybe a <form> wrapper has to be added
+ Be aware that nested buttons then trigger a submission of the form (-> ct:spinnerwithinphty)
+ --%>
+ <fieldset>
+ <div class="form-group">
+ <label for="nodetemplateid">Id</label>
+ <input id="nodetemplateid" disabled="disabled" class="form-control"></input>
+ </div>
+ <div class="form-group">
+ <label for="nodetemplatename" class="control-label">Name</label>
+ <input id="nodetemplatename" name="name" class="form-control"/>
+ </div>
+ <div class="form-group">
+ <label for="nodetemplateType">Type</label>
+ <%-- filled by fillInformationSection --%>
+ <a id="nodetemplateType" target="_blank" href="#" class="form-control"></a>
+ </div>
+ <ct:spinnerwithinphty min="0" width="10" changedfunction="minInstancesChanged" label="min" id="minInstances" />
+ <ct:spinnerwithinphty min="1" width="10" changedfunction="maxInstancesChanged" label="max" id="maxInstances" withinphty="true" />
+ </fieldset>
+ </div>
+
+</div>
+
+<script>
+ function minInstancesChanged(event, ui) {
+ var val;
+ if (ui === undefined) {
+ val = $("#minInstances").val();
+ } else {
+ val = ui.value;
+ }
+ ntMin.html(val);
+ }
+
+ function maxInstancesChanged(event, ui) {
+ var val;
+ if (ui === undefined) {
+ val = $("#maxInstances").val();
+ } else {
+ val = ui.value;
+ }
+ ntMax.html(val);
+ }
+
+ // the name input field of the properties section
+ var nameInput = $("#nodetemplatename");
+
+ // the min/max fields of the currently selected node template
+ var ntMin;
+ var ntMax;
+
+ function fillInformationSection(nodeTemplate) {
+ require(["winery-support-common"], function(wsc) {
+ // currently doesn't help for a delayed update
+ //informationSection.slideDown();
+
+ $("#nodetemplateid").val(nodeTemplate.attr("id"));
+
+ var headerContainer = nodeTemplate.children("div.headerContainer");
+
+ // copy name
+ var nameField = headerContainer.children("div.name");
+ var name = nameField.text();
+ nameInput.val(name);
+
+ // copy type
+ var typeQName = headerContainer.children("span.typeQName").text();
+ var href = wsc.makeNodeTypeURLFromQName("${repositoryURL}", typeQName);
+ var type = headerContainer.children("div.type").text();
+ $("#nodetemplateType").attr("href", href).text(type);
+
+ // we could use jQuery-typing, but it is not possible to replace key events there
+ nameInput.off("keyup");
+ nameInput.on("keyup", function() {
+ nameField.text($(this).val());
+ });
+
+ // handling of min and max
+ ntMin = nodeTemplate.children(".headerContainer").children(".minMaxInstances").children(".minInstances");
+ $("#minInstances").val(ntMin.text());
+ ntMax = nodeTemplate.children(".headerContainer").children(".minMaxInstances").children(".maxInstances");
+ $("#maxInstances").val(ntMax.text());
+ });
+ }
+
+ function showViewOnTheRight() {
+ $("#NTPropertiesView").fadeIn();
+ }
+
+ function hideViewOnTheRight() {
+ $("#NTPropertiesView").fadeOut();
+ }
+
+$(function() {
+ winery.events.register(
+ winery.events.name.SELECTION_CHANGED,
+ function() {
+ // min/max instances do not lost focus if other shape is clicked
+ // workaround
+ if ($("#minInstances").is(":focus")) {
+ minInstancesChanged();
+ }
+ if ($("#maxInstances").is(":focus")) {
+ maxInstancesChanged();
+ }
+ var nodeTemplate = $("div.NodeTemplateShape.selected");
+ var numSelected = nodeTemplate.length;
+ if (numSelected == 1) {
+ fillInformationSection(nodeTemplate);
+ showViewOnTheRight();
+ } else {
+ hideViewOnTheRight();
+ }
+ }
+ );
+});
+</script>
diff --git a/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/reqscaps/addorupdatereqorcap.tag b/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/reqscaps/addorupdatereqorcap.tag
new file mode 100644
index 0000000..0ec6f5d
--- /dev/null
+++ b/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/reqscaps/addorupdatereqorcap.tag
@@ -0,0 +1,248 @@
+<%--
+/*******************************************************************************
+ * Copyright (c) 2012-2014 University of Stuttgart.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ * Oliver Kopp - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+--%>
+<%@tag description="Dialog to change a req or cap. Offers function showEditDiagFor${shortName}(id)" pageEncoding="UTF-8"%>
+
+<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates" %>
+<%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%>
+<%@taglib prefix="w" tagdir="/WEB-INF/tags"%>
+<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%>
+
+<%@attribute name="headerLabel" required="true"%>
+<%@attribute name="shortName" required="true" description="Used for diag id, function name suffix, Req|Cap"%>
+<%@attribute name="requirementOrCapability" required="true" description="requirement|capability"%>
+<%@attribute name="cssClassPrefix" required="true"%>
+<%@attribute name="allTypes" required="true" type="java.util.Collection" description="Collection&lt;QName&gt; of all available types" %>
+<%@attribute name="clazz" required="true" type="java.lang.Class" description="TRequirement.class or TCapability.class" %>
+<%@attribute name="repositoryURL" required="true" %>
+
+<div class="modal fade" id="AddOrUpdate${shortName}Diag">
+ <div class="modal-dialog">
+ <div class="modal-content" style="width:660px;">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+ <h4 class="modal-title"><span id="headerAddOrUpdate"></span> ${headerLabel}</h4>
+ </div>
+ <div class="modal-body">
+ <form id="add${shortName}Form" enctype="multipart/form-data">
+ <fieldset>
+ <w:idInput inputFieldId="${shortName}Id"/>
+
+ <div class="form-group">
+ <label for="${shortName}NameChooser" class="control-label">Definition Name:</label>
+ <input id="${shortName}NameChooser" class="form-control" type="text" required="required" />
+ </div>
+
+ <div class="form-group">
+ <label for="${shortName}TypeDisplay" class="control-label">${shortName} Type:</label>
+ <input id="${shortName}TypeDisplay" class="form-control" type="text" required="required" disabled="disabled"/>
+ </div>
+
+ <div id="${shortName}PropertiesContainer">
+ </div>
+ </fieldset>
+ </form>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
+ <button type="button" id="add${shortName}btn" class="btn btn-primary" onclick="addOrUpdate${shortName}(false);">Add</button>
+ <button type="button" id="delete${shortName}btn" class="btn btn-danger" onclick="deleteCurrent${shortName}();">Delete</button>
+ <button type="button" id="update${shortName}btn" class="btn btn-primary" onclick="addOrUpdate${shortName}(true);">Change</button>
+ </div>
+ </div>
+ </div>
+</div>
+
+<script>
+
+/*
+ * The following variables are declared twice due to double inclusion of this .tag flie
+ * Due to JavaScript magic, it works nevertheless
+ */
+var selectedNodeTemplateForReqCapAddition;
+
+//global variable set by editPropertiesXML and read by save${shortName}Edits
+var nodeTemplateEditedReqOrCap;
+
+
+function deleteCurrent${shortName}() {
+ nodeTemplateEditedReqOrCap.remove();
+ $("#AddOrUpdate${shortName}Diag").modal("hide");
+}
+
+function update${shortName}PropertiesContainerWithClone(propertiesContainerToClone) {
+ var clone = propertiesContainerToClone.clone();
+ $("#${shortName}PropertiesContainer").empty().append(clone);
+ clone.find(".KVPropertyValue").editable({mode: "inline"});
+}
+
+function update${shortName}PropertiesFromSelectedType() {
+ var data = $("#${shortName}NameChooser").select2("data");
+ var name = data.text;
+ var type = data.id;
+
+ // fill in type
+ // TODO: use qname2href and store QName in data-qname for later consumption -- possibly qname2href should always store the qname in data-qname
+ $("#${shortName}TypeDisplay").val(type);
+
+ // fill in properties (derived from type)
+ var propertiesContainer= $(".skelettonPropertyEditorFor${shortName} > span:contains('" + type + "')").parent().children("div");
+ update${shortName}PropertiesContainerWithClone(propertiesContainer);
+}
+
+$("#${shortName}NameChooser").on("change", function(e) {
+ update${shortName}PropertiesFromSelectedType();
+});
+
+/**
+ * Called when a req/cap should be added or updated
+ * Update mode is triggered if reqOrCapIdtoUpdate is given
+ *
+ * @param nodeTemplateId the node template id to add a req/cap to. undefined in update mode
+ * @param reqOrCapIdtoUpdate
+ */
+function showAddOrUpdateDiagFor${shortName}(nodeTemplateId, reqOrCapIdToUpdate) {
+ var update = (typeof reqOrCapIdToUpdate !== "undefined");
+
+ if (update) {
+ nodeTemplateEditedReqOrCap = $("#" + reqOrCapIdToUpdate);
+ // in update mode, nodeTemplateId is not provided, we have to search for the right shape
+ selectedNodeTemplateForReqCapAddition = nodeTemplateEditedReqOrCap.closest(".NodeTemplateShape");
+ } else {
+ selectedNodeTemplateForReqCapAddition = $("#" + nodeTemplateId);
+ }
+
+ require(["winery-support-common"], function(wsc) {
+ var typeQName = selectedNodeTemplateForReqCapAddition.children("div.headerContainer").children("span.typeQName").text();
+ var urlFragment = wsc.getURLFragmentOutOfFullQName(typeQName);
+ var url = "${repositoryURL}/nodetypes/" + urlFragment + "/${requirementOrCapability}definitions/";
+ $.ajax({
+ url: url,
+ dataType: "json"
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ vShowAJAXError("Could not fetch ${requirementOrCapability} definitions", jqXHR, errorThrown);
+ }).done(function(data) {
+ // now, we have all available requirement definitions
+ // we have to ask each of it for the type
+ // we use the type as key for the option and the name as displayed text
+ // select2 perfectly handles duplicate keys
+
+ var select2Data = [];
+
+ $.each(data, function(i,e) {
+ var rqDefURL = url + e + "/type";
+ $.ajax({
+ url: rqDefURL,
+ async: false,
+ dataType: "text"
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ vShowAJAXError("Could not fetch type for " + e, jqXHR, errorThrown);
+ }).done(function(data) {
+ var item = {
+ id: data,
+ text: e
+ };
+ select2Data.push(item);
+ });
+ });
+
+ $("#${shortName}NameChooser").select2({
+ placeholder: "Select name",
+ data: select2Data
+ });
+
+ if (update) {
+ $("#add${shortName}btn").hide();
+ $("#update${shortName}btn").show();
+ $("#delete${shortName}btn").show();
+ $("#headerAddOrUpdate").text("Change");
+
+ // collect existing data in variables
+ var id = nodeTemplateEditedReqOrCap.children(".id").text();
+ var name = nodeTemplateEditedReqOrCap.children(".name").text();
+ var type = nodeTemplateEditedReqOrCap.children(".type").children("a").data("qname");
+ var propertiesContainer = nodeTemplateEditedReqOrCap.children(".propertiesContainer");
+
+ // update displays
+
+ // id
+ $("#${shortName}Id").val(id);
+
+ // name
+ // we use the type as key at NameChooser. We hope that there are no duplicates. Otherwise, update won't work.
+ $("#${shortName}NameChooser").select2("val", type);
+ // make consistency check
+ var data = $("#${shortName}NameChooser").select2("data");
+ if (data == null) {
+ vShowError("type " + type + " could not be selected.")
+ } else if (name != (data.text)) {
+ vShowError("There are two names for different types. That case is not handled in the UI.");
+ }
+
+ // type
+ $("#${shortName}TypeDisplay").val(type);
+
+ // properties
+ update${shortName}PropertiesContainerWithClone(propertiesContainer);
+ } else {
+ $("#add${shortName}btn").show();
+ $("#update${shortName}btn").hide();
+ $("#delete${shortName}btn").hide();
+ $("#headerAddOrUpdate").text("Add");
+
+ // QUICK HACK if dialog has been shown before -> show properties of selected type
+ if ($("#${shortName}NameChooser").select2("data") != null) {
+ update${shortName}PropertiesFromSelectedType();
+ }
+ }
+
+ $("#AddOrUpdate${shortName}Diag").modal("show");
+ });
+ });
+}
+
+/**
+ * Called at click on button "Add" or "Change"
+ */
+function addOrUpdate${shortName}(update) {
+ if (highlightRequiredFields()) {
+ vShowError("Please fill in all required fields");
+ return;
+ }
+ require(["tmpl"], function(tmpl) {
+ // Generate skeletton div
+ var sel2data = $("#${shortName}NameChooser").select2("data");
+ var data = {
+ id: $("#${shortName}Id").val(),
+ name: sel2data.text,
+ type: sel2data.id
+ }
+ // tmpl-${shortName} is defined in reqsorcaps.tag
+ var div = tmpl("tmpl-${shortName}", data);
+
+ // Add the div to the node template
+ if (update) {
+ nodeTemplateEditedReqOrCap.replaceWith(div);
+ } else {
+ selectedNodeTemplateForReqCapAddition.children(".${cssClassPrefix}Container").children(".content").children(".addnewreqorcap").before(div);
+ }
+
+ // Put properties at the right place
+ $("#toBeReplacedByProperties").replaceWith($("#${shortName}PropertiesContainer").children());
+
+ $("#AddOrUpdate${shortName}Diag").modal("hide");
+ });
+}
+
+</script>
diff --git a/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/relationshiptemplates/propertiesOfOneRelationshipTemplate.tag b/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/relationshiptemplates/propertiesOfOneRelationshipTemplate.tag
new file mode 100644
index 0000000..8c63dca
--- /dev/null
+++ b/winery/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/relationshiptemplates/propertiesOfOneRelationshipTemplate.tag
@@ -0,0 +1,179 @@
+<%--
+/*******************************************************************************
+ * Copyright (c) 2012-2014 University of Stuttgart.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and the Apache License 2.0 which both accompany this distribution,
+ * and are available at http://www.eclipse.org/legal/epl-v10.html
+ * and http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Contributors:
+ * Oliver Kopp - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+--%>
+<%@tag language="java" pageEncoding="UTF-8" description="Renders the properies of one relationship tempate on the right"%>
+
+<%@attribute name="relationshipTypes" required="true" type="java.util.Collection" %>
+<%@attribute name="repositoryURL" required="true" type="java.lang.String" description="The repository URL"%>
+
+<link rel="stylesheet" href="css/propertiesview.css" />
+
+<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
+<%@taglib prefix="props" tagdir="/WEB-INF/tags/common/templates" %>
+<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions" %>
+
+<div id="RTPropertiesView" class="propertiesView" style="display: none;">
+
+ <div id="relationshipTemplateInformationSection">
+ <fieldset>
+ <div class="form-group">
+ <label for="relationshiptemplateid">Id</label>
+ <input id="relationshiptemplateid" disabled="disabled" class="form-control"></input>
+ </div>
+ <div class="form-group">
+ <label for="relationshiptemplatename" class="control-label">Name</label>
+ <a href="#" id="relationshiptemplatename" data-title="Name" data-type="text" class="form-control"></a>
+ </div>
+ <div class="form-group">
+ <label for="relationshipType">Type</label>
+ <%-- filled by showRTViewOnTheRight --%>
+ <a id="relationshipType" target="_blank" href="#" class="form-control"></a>
+ </div>
+ <div class="form-group">
+ <label for="RTreq" class="control-label">Requirement</label>
+ <select id="RTreq" class="form-control">
+ </select>
+ </div>
+ <div class="form-group">
+ <label for="RTcap" class="control-label">Capability</label>
+ <select id="RTcap" class="form-control">
+ </select>
+ </div>
+ </fieldset>
+ </div>
+
+</div>
+
+<script>
+
+ var currentlySelectedConn = null;
+
+ /**
+ * Fills the requirement and capabilities dropdowns with the available reqs and caps (which are defined at the source/target node template)
+ *
+ * @param conn the connection itself
+ * @param dataField = "req"|"cap"
+ * @param sourceDivClass = requirementsContainer | capabilitiesContainer
+ */
+ function fillReqOrCap(conn, dataField, nodetemplateId, sourceDivClass, targetSelect) {
+ var nt = $("#" + nodetemplateId);
+ var reqsOrCaps = nt.children("." + sourceDivClass).children(".content").children(".reqorcap");
+ var connReqCap = winery.connections[conn.id][dataField];
+
+ targetSelect.empty();
+
+ var optData = {
+ value: "__NONE__",
+ text: "(none)"
+ };
+ if (!connReqCap) {
+ selected: true
+ }
+ require(["tmpl"], function(tmpl) {
+ var newOption = tmpl("tmpl-option", optData);
+ targetSelect.append(newOption);
+
+ reqsOrCaps.each(function(i,e) {
+ optData.value = $(e).children(".id").children("span.id").text();
+ optData.text = $(e).children(".name").children("span.name").text();
+ optData.selected = (optData.value == connReqCap);
+ newOption = tmpl("tmpl-option", optData);
+ targetSelect.append(newOption);
+ });
+ });
+
+ targetSelect.off("change");
+ targetSelect.on("change", function(e) {
+ var val = targetSelect.val();
+ if (val == "__NONE__") {
+ delete(winery.connections[conn.id][dataField]);
+ } else {
+ winery.connections[conn.id][dataField] = val;
+ }
+ });
+ }
+
+ function fillType(nsAndLocalName) {
+ require(["winery-support-common"], function(wsc) {
+ var href = wsc.makeRelationshipTypeURLFromNSAndLocalName("${repositoryURL}", nsAndLocalName);
+ // localname is always the name of the relationship type because the specification requires a "name" attribute only and does not foresee an "id" attribute
+ $("#relationshipType").attr("href", href).text(nsAndLocalName.localname);
+ })
+ }
+
+ function displayProperties(connData) {
+ $("#RTPropertiesView").append(connData.propertiesContainer);
+ }
+
+ /**
+ * @param conn the jsPlumb connection
+ */
+ function showRTViewOnTheRight(conn) {
+ currentlySelectedConn = conn;
+
+ $("#RTPropertiesView").fadeIn();
+
+ $("#relationshiptemplateid").val(winery.connections[conn.id].id);
+ $("#relationshiptemplatename").editable('setValue', winery.connections[conn.id].name);
+ fillReqOrCap(conn, "req", conn.sourceId, "requirementsContainer", $("#RTreq"));
+ fillReqOrCap(conn, "cap", conn.targetId, "capabilitiesContainer", $("#RTcap"));
+ fillType(winery.connections[conn.id].nsAndLocalName);
+ displayProperties(winery.connections[conn.id]);
+ }
+
+ function hideRTViewOnTheRight() {
+ if (currentlySelectedConn == null) {
+ // nothing to do if no relationship template is selected
+ return;
+ }
+
+ $("#RTPropertiesView").fadeOut();
+
+ // user will see some flickering here, but we don't want to set timers -> could lead to race conditions
+ $("#skelettonContainerForRelationshipTemplates").append(winery.connections[currentlySelectedConn.id].propertiesContainer);
+ currentlySelectedConn = null;
+ }
+
+ function storeUpdatedName(newName) {
+ currentlySelectedConn.name = newName;
+ }
+
+ $(function() {
+ $("#relationshiptemplatename").editable({
+ success: function(response, newValue) {
+ currentlySelectedConn.name = newValue;
+ }
+ });
+ });
+
+ function unselectAllConnections() {
+ jsPlumb.select().each(function(connection) {
+ connection.removeType("selected");
+ });
+ }
+
+ winery.events.register(
+ winery.events.name.SELECTION_CHANGED,
+ function() {
+ var nodeTemplate = $("div.NodeTemplateShape.selected");
+ var numSelected = nodeTemplate.length;
+ if (numSelected != 0) {
+ // if node templates are selected, no RT properties should be shown
+ hideRTViewOnTheRight();
+
+ unselectAllConnections();
+ }
+ }
+ );
+
+</script>