| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| define(["dojo/_base/xhr", |
| "dojo/_base/array", |
| "dojo/_base/event", |
| "dojo/_base/lang", |
| "dojo/json", |
| "dojo/dom-construct", |
| "dojo/dom-geometry", |
| "dojo/dom-style", |
| "dojo/_base/window", |
| "dojo/query", |
| "dojo/parser", |
| "dojo/store/Memory", |
| "dojo/window", |
| "dojo/on", |
| "dojox/html/entities", |
| "qpid/common/metadata", |
| "qpid/common/widgetconfigurer", |
| "dijit/registry", |
| "dijit/TitlePane", |
| "dijit/Dialog", |
| "dijit/form/Form", |
| "dijit/form/Button", |
| "dijit/form/RadioButton", |
| "dijit/form/CheckBox", |
| "dijit/form/FilteringSelect", |
| "dijit/form/ValidationTextBox", |
| "dojox/layout/TableContainer", |
| "dijit/layout/ContentPane", |
| "dojox/validate/us", |
| "dojox/validate/web", |
| "dojo/domReady!" |
| ], |
| function (xhr, array, event, lang, json, dom, geometry, domStyle, win, query, parser, Memory, w, on, entities, metadata, widgetconfigurer, registry) { |
| var util = {}; |
| if (Array.isArray) { |
| util.isArray = function (object) { |
| return Array.isArray(object); |
| }; |
| } else { |
| util.isArray = function (object) { |
| return object instanceof Array; |
| }; |
| } |
| |
| util.flattenStatistics = function (data) { |
| var attrName, stats, propName, theList; |
| for(attrName in data) { |
| if(data.hasOwnProperty(attrName)) { |
| if(attrName == "statistics") { |
| stats = data.statistics; |
| for(propName in stats) { |
| if(stats.hasOwnProperty( propName )) { |
| data[ propName ] = stats[ propName ]; |
| } |
| } |
| } else if(data[ attrName ] instanceof Array) { |
| theList = data[ attrName ]; |
| |
| for(var i=0; i < theList.length; i++) { |
| util.flattenStatistics( theList[i] ); |
| } |
| } |
| } |
| } |
| }; |
| |
| util.isReservedExchangeName = function(exchangeName) |
| { |
| return exchangeName == null || exchangeName == "" || "<<default>>" == exchangeName || exchangeName.indexOf("amq.") == 0 || exchangeName.indexOf("qpid.") == 0; |
| }; |
| |
| util.deleteGridSelections = function(updater, grid, url, confirmationMessageStart, idParam) |
| { |
| var data = grid.selection.getSelected(); |
| var success = false; |
| if(data.length) |
| { |
| var confirmationMessage = null; |
| if (data.length == 1) |
| { |
| confirmationMessage = confirmationMessageStart + " '" + data[0].name + "'?"; |
| } |
| else |
| { |
| var names = ''; |
| for(var i = 0; i<data.length; i++) |
| { |
| if (names) |
| { |
| names += ', '; |
| } |
| names += "\""+ data[i].name + "\""; |
| } |
| confirmationMessage = confirmationMessageStart + "s " + names + "?"; |
| } |
| if(confirm(confirmationMessage)) |
| { |
| var i, queryParam; |
| for(i = 0; i<data.length; i++) |
| { |
| if(queryParam) |
| { |
| queryParam += "&"; |
| } |
| else |
| { |
| queryParam = "?"; |
| } |
| queryParam += ( idParam || "id" ) + "=" + encodeURIComponent(data[i].id); |
| } |
| var query = url + queryParam; |
| var failureReason = ""; |
| xhr.del({url: query, sync: true, handleAs: "json"}).then( |
| function(data) |
| { |
| success = true; |
| grid.selection.deselectAll(); |
| if (updater) |
| { |
| updater.update(); |
| } |
| }, |
| function(error) {success = false; failureReason = error;}); |
| if(!success ) |
| { |
| util.xhrErrorHandler(failureReason); |
| } |
| } |
| } |
| return success; |
| } |
| |
| util.isProviderManagingUsers = function(type) |
| { |
| return (type === "PlainPasswordFile" || type === "Base64MD5PasswordFile" || type === "SCRAM-SHA-1" |
| || type === "SCRAM-SHA-256" || type === "Plain" || type === "MD5" ); |
| }; |
| |
| util.showSetAttributesDialog = function(attributeWidgetFactories, data, putURL, dialogTitle, category, type, appendNameToUrl) |
| { |
| var layout = new dojox.layout.TableContainer({ |
| cols: 1, |
| "labelWidth": "300", |
| showLabels: true, |
| orientation: "horiz", |
| customClass: "formLabel" |
| }); |
| var submitButton = new dijit.form.Button({label: "Submit", type: "submit"}); |
| var form = new dijit.form.Form(); |
| |
| var dialogContent = dom.create("div"); |
| var dialogContentArea = dom.create("div", {"style": {width: 600}}); |
| var dialogActionBar = dom.create("div", { "class": "dijitDialogPaneActionBar"} ); |
| dialogContent.appendChild(dialogContentArea); |
| dialogContent.appendChild(dialogActionBar); |
| dialogContentArea.appendChild(layout.domNode) |
| dialogActionBar.appendChild(submitButton.domNode); |
| form.domNode.appendChild(dialogContent); |
| |
| var widgets = {}; |
| var requiredFor ={}; |
| var groups = {}; |
| for(var i in attributeWidgetFactories) |
| { |
| var attributeWidgetFactory = attributeWidgetFactories[i]; |
| var widget = attributeWidgetFactory.createWidget(data); |
| var name = attributeWidgetFactory.name ? attributeWidgetFactory.name : widget.name; |
| widgets[name] = widget; |
| var dotPos = name.indexOf("."); |
| if (dotPos == -1) |
| { |
| if (widget instanceof dijit.layout.ContentPane) |
| { |
| dialogContentArea.appendChild(widget.domNode); |
| } |
| else |
| { |
| layout.addChild(widget); |
| } |
| } |
| else |
| { |
| var groupName = name.substring(0, dotPos); |
| var groupFieldContainer = null; |
| if (groups.hasOwnProperty(groupName)) |
| { |
| groupFieldContainer = groups[groupName]; |
| } |
| else |
| { |
| groupFieldContainer = new dojox.layout.TableContainer({ |
| cols: 1, |
| "labelWidth": "300", |
| showLabels: true, |
| orientation: "horiz", |
| customClass: "formLabel" |
| }); |
| groups[groupName] = groupFieldContainer; |
| var groupTitle = attributeWidgetFactory.groupName ? attributeWidgetFactory.groupName : |
| groupName.charAt(0).toUpperCase() + groupName.slice(1); |
| var panel = new dijit.TitlePane({title: groupTitle, content: groupFieldContainer.domNode}); |
| dialogContentArea.appendChild(dom.create("br")); |
| dialogContentArea.appendChild(panel.domNode); |
| } |
| groupFieldContainer.addChild(widget); |
| } |
| if (attributeWidgetFactory.hasOwnProperty("requiredFor") && !data[name]) |
| { |
| requiredFor[attributeWidgetFactory.requiredFor] = widget; |
| } |
| } |
| |
| this.applyMetadataToWidgets(dialogContent, category, type); |
| |
| // add onchange handler to set required property for dependent widget |
| for(var widgetName in requiredFor) |
| { |
| var dependent = requiredFor[widgetName]; |
| var widget = widgets[widgetName]; |
| if (widget) |
| { |
| widget.dependent = dependent; |
| widget.on("change", function(newValue){ |
| this.dependent.set("required", newValue != ""); |
| }); |
| } |
| } |
| var setAttributesDialog = new dijit.Dialog({ |
| title: dialogTitle, |
| content: form |
| }); |
| form.on("submit", function(e) |
| { |
| event.stop(e); |
| try |
| { |
| if(form.validate()) |
| { |
| var values = {}; |
| var formWidgets = form.getDescendants(); |
| for(var i in formWidgets) |
| { |
| var widget = formWidgets[i]; |
| var value = widget.value; |
| var propName = widget.name; |
| if (propName && !widget.disabled){ |
| if ((widget instanceof dijit.form.CheckBox || widget instanceof dijit.form.RadioButton)) { |
| if (widget.checked != widget.initialValue) { |
| values[ propName ] = widget.checked; |
| } |
| } else if (value != widget.initialValue) { |
| values[ propName ] = value ? value: null; |
| } |
| } |
| } |
| |
| var that = this; |
| var url = putURL; |
| if (appendNameToUrl){ |
| url = url + "/" + encodeURIComponent(values["name"]); |
| } |
| xhr.put({url: url , sync: true, handleAs: "json", |
| headers: { "Content-Type": "application/json"}, |
| putData: json.stringify(values), |
| load: function(x) {that.success = true; }, |
| error: function(error) {that.success = false; that.failureReason = error;}}); |
| if(this.success === true) |
| { |
| setAttributesDialog.destroy(); |
| } |
| else |
| { |
| util.xhrErrorHandler(this.failureReason); |
| |
| } |
| return false; |
| } |
| else |
| { |
| alert('Form contains invalid data. Please correct first'); |
| return false; |
| } |
| } |
| catch(e) |
| { |
| alert("Unexpected exception:" + e.message); |
| return false; |
| } |
| }); |
| form.connectChildren(true); |
| setAttributesDialog.startup(); |
| var formWidgets = form.getDescendants(); |
| var aproximateHeight = 0; |
| for(var i in formWidgets){ |
| var widget = formWidgets[i]; |
| var propName = widget.name; |
| if (propName) { |
| if ((widget instanceof dijit.form.CheckBox || widget instanceof dijit.form.RadioButton)) { |
| widget.initialValue = widget.checked; |
| } else { |
| widget.initialValue = widget.value; |
| } |
| aproximateHeight += 30; |
| } |
| } |
| dialogContentArea.style.overflow= "auto"; |
| dialogContentArea.style.height = "300"; |
| setAttributesDialog.on("hide", function(e){setAttributesDialog.destroy();}); |
| setAttributesDialog.show(); |
| }; |
| |
| util.findAllWidgets = function(root) |
| { |
| return query("[widgetid]", root).map(registry.byNode).filter(function(w){ return w;}); |
| }; |
| |
| util.xhrErrorHandler = function(error) |
| { |
| var fallback = "Unexpected error - see server logs"; |
| var statusCodeNode = dojo.byId("errorDialog.statusCode"); |
| var errorMessageNode = dojo.byId("errorDialog.errorMessage"); |
| var userMustReauth = false; |
| |
| if (error) |
| { |
| if (error.hasOwnProperty("status")) |
| { |
| var hasMessage = error.hasOwnProperty("message"); |
| var message; |
| |
| if (error.status == 0) |
| { |
| message = "Unable to contact the Broker"; |
| } |
| else if (error.status == 401) |
| { |
| message = "Authentication required"; |
| userMustReauth = true; |
| } |
| else if (error.status == 403) |
| { |
| message = "Access Forbidden"; |
| } |
| else |
| { |
| message = hasMessage ? error.message : fallback; |
| |
| // Try for a more detail error sent by the Broker as json |
| if (error.hasOwnProperty("responseText")) |
| { |
| try |
| { |
| var errorObj = json.parse(error.responseText); |
| message = errorObj.hasOwnProperty("errorMessage") ? errorObj.errorMessage : errorMessageNode; |
| } |
| catch (e) |
| { |
| // Ignore |
| } |
| } |
| } |
| |
| errorMessageNode.innerHTML = entities.encode(message ? message : fallback); |
| statusCodeNode.innerHTML = entities.encode(String(error.status)); |
| |
| dojo.byId("errorDialog.advice.retry").style.display = userMustReauth ? "none" : "block"; |
| dojo.byId("errorDialog.advice.reconnect").style.display = userMustReauth ? "block" : "none"; |
| |
| domStyle.set(registry.byId("errorDialog.button.cancel").domNode, 'display', userMustReauth ? "none" : "block"); |
| domStyle.set(registry.byId("errorDialog.button.relogin").domNode, 'display', userMustReauth ? "block" : "none"); |
| |
| } |
| else |
| { |
| statusCodeNode.innerHTML = ""; |
| errorMessageNode.innerHTML = fallback; |
| } |
| |
| var dialog = dijit.byId("errorDialog"); |
| if (!dialog.open) |
| { |
| dialog.show(); |
| } |
| } |
| }; |
| |
| util.sendRequest = function (url, method, attributes, sync) |
| { |
| var success = false; |
| var failureReason = ""; |
| var syncRequired = sync == undefined ? true : sync; |
| if (method == "POST" || method == "PUT") |
| { |
| xhr.put({ |
| url: url, |
| sync: syncRequired, |
| handleAs: "json", |
| headers: { "Content-Type": "application/json"}, |
| putData: json.stringify(attributes), |
| load: function(x) {success = true; }, |
| error: function(error) {success = false; failureReason = error;} |
| }); |
| } |
| else if (method == "DELETE") |
| { |
| xhr.del({url: url, sync: syncRequired, handleAs: "json"}).then( |
| function(data) { success = true; }, |
| function(error) {success = false; failureReason = error;} |
| ); |
| } |
| |
| if (syncRequired && !success) |
| { |
| util.xhrErrorHandler(failureReason); |
| } |
| return success; |
| } |
| |
| util.equals = function(object1, object2) |
| { |
| if (object1 && object2) |
| { |
| if (typeof object1 != typeof object2) |
| { |
| return false; |
| } |
| else |
| { |
| if (object1 instanceof Array || typeof object1 == "array") |
| { |
| if (object1.length != object2.length) |
| { |
| return false; |
| } |
| |
| for (var i = 0, l=object1.length; i < l; i++) |
| { |
| var item = object1[i]; |
| if (item && (item instanceof Array || typeof item == "array" || item instanceof Object)) |
| { |
| if (!this.equals(item, object2[i])) |
| { |
| return false; |
| } |
| } |
| else if (item != object2[i]) |
| { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| else if (object1 instanceof Object) |
| { |
| for (propName in object1) |
| { |
| if (object1.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) |
| { |
| return false; |
| } |
| else if (typeof object1[propName] != typeof object2[propName]) |
| { |
| return false; |
| } |
| } |
| |
| for(propName in object2) |
| { |
| var object1Prop = object1[propName]; |
| var object2Prop = object2[propName]; |
| |
| if (object2.hasOwnProperty(propName) != object1.hasOwnProperty(propName)) |
| { |
| return false; |
| } |
| else if (typeof object1Prop != typeof object2Prop) |
| { |
| return false; |
| } |
| |
| if(!object2.hasOwnProperty(propName)) |
| { |
| // skip functions |
| continue; |
| } |
| |
| if (object1Prop && (object1Prop instanceof Array || typeof object1Prop == "array" || object1Prop instanceof Object)) |
| { |
| if (!this.equals(object1Prop, object2Prop)) |
| { |
| return false; |
| } |
| } |
| else if(object1Prop != object2Prop) |
| { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| } |
| return object1 === object2; |
| } |
| |
| util.parseHtmlIntoDiv = function(containerNode, htmlTemplateLocation) |
| { |
| xhr.get({url: htmlTemplateLocation, |
| sync: true, |
| load: function(template) { |
| containerNode.innerHTML = template; |
| parser.parse(containerNode); |
| }}); |
| } |
| util.buildUI = function(containerNode, parent, htmlTemplateLocation, fieldNames, obj) |
| { |
| this.parseHtmlIntoDiv(containerNode, htmlTemplateLocation); |
| if (fieldNames && obj) |
| { |
| for(var i=0; i<fieldNames.length;i++) |
| { |
| var fieldName = fieldNames[i]; |
| obj[fieldName]= query("." + fieldName, containerNode)[0]; |
| } |
| } |
| } |
| |
| util.buildEditUI = function(containerNode, htmlTemplateLocation, fieldNamePrefix, fieldNames, data) |
| { |
| this.parseHtmlIntoDiv(containerNode, htmlTemplateLocation); |
| if (fieldNames) |
| { |
| for(var i = 0; i < fieldNames.length; i++) |
| { |
| var fieldName = fieldNames[i]; |
| var widget = registry.byId(fieldNamePrefix + fieldName); |
| widget.set("value", data[fieldName]); |
| } |
| } |
| } |
| |
| util.updateUI = function(data, fieldNames, obj) |
| { |
| for(var i=0; i<fieldNames.length;i++) |
| { |
| var fieldName = fieldNames[i]; |
| var value = data[fieldName]; |
| obj[fieldName].innerHTML= (value == undefined || value == null) ? "" : entities.encode(String(value)); |
| } |
| } |
| |
| util.applyMetadataToWidgets = function(domRoot, category, type) |
| { |
| var widgets = util.findAllWidgets(domRoot); |
| array.forEach(widgets, |
| function (widget) |
| { |
| widgetconfigurer.config(widget, category, type); |
| }); |
| } |
| |
| util.getFormWidgetValues = function (form, initialData) |
| { |
| var values = {}; |
| var formWidgets = form.getChildren(); |
| for(var i in formWidgets) |
| { |
| var widget = formWidgets[i]; |
| var value = widget.value; |
| var propName = widget.name; |
| if (propName && (widget.required || value )) |
| { |
| if (widget.excluded) |
| { |
| continue; |
| } |
| if (widget.contextvar) |
| { |
| var context = values["context"]; |
| if (!context) |
| { |
| context = {}; |
| values["context"] = context; |
| } |
| context[propName]=String(value); |
| } |
| else if (widget instanceof dijit.form.RadioButton) |
| { |
| if (widget.checked) |
| { |
| var currentValue = values[propName]; |
| if (currentValue) |
| { |
| if (lang.isArray(currentValue)) |
| { |
| currentValue.push(value) |
| } |
| else |
| { |
| values[ propName ] = [currentValue, value]; |
| } |
| } |
| else |
| { |
| values[ propName ] = value; |
| } |
| } |
| } |
| else if (widget instanceof dijit.form.CheckBox) |
| { |
| values[ propName ] = widget.checked; |
| } |
| else |
| { |
| if (widget.get("type") == "password") |
| { |
| if (value) |
| { |
| values[ propName ] = value; |
| } |
| } |
| else |
| { |
| values[ propName ] = value ? value: null; |
| } |
| } |
| } |
| } |
| if (initialData) |
| { |
| for(var propName in values) |
| { |
| if (values[propName] == initialData[propName]) |
| { |
| delete values[propName]; |
| } |
| } |
| } |
| return values; |
| } |
| |
| util.updateUpdatableStore = function(updatableStore, data) |
| { |
| var currentRowCount = updatableStore.grid.rowCount; |
| updatableStore.grid.domNode.style.display = data ? "block" : "none"; |
| updatableStore.update(data || []); |
| if (data) |
| { |
| if (currentRowCount == 0 && data.length == 1) |
| { |
| // grid with a single row is not rendering properly after being hidden |
| // force rendering |
| updatableStore.grid.render(); |
| } |
| } |
| } |
| |
| util.makeTypeStore = function (types) |
| { |
| var typeData = []; |
| for (var i = 0; i < types.length; i++) { |
| var type = types[i]; |
| typeData.push({id: type, name: type}); |
| } |
| return new Memory({ data: typeData }); |
| } |
| |
| util.setMultiSelectOptions = function(multiSelectWidget, options) |
| { |
| util.addMultiSelectOptions(multiSelectWidget, options, true); |
| } |
| |
| util.addMultiSelectOptions = function(multiSelectWidget, options, clearExistingOptions) |
| { |
| if (clearExistingOptions) |
| { |
| var children = multiSelectWidget.children; |
| var initialLength = children.length; |
| for (var i = initialLength - 1; i >= 0 ; i--) |
| { |
| var child = children.item(i); |
| multiSelectWidget.removeChild(child); |
| } |
| } |
| for (var i = 0; i < options.length; i++) |
| { |
| // construct new option for list |
| var newOption = win.doc.createElement('option'); |
| var value = options[i]; |
| newOption.innerHTML = value; |
| newOption.value = value; |
| |
| // add new option to list |
| multiSelectWidget.appendChild(newOption); |
| } |
| } |
| |
| var singleContextVarRegexp = "(\\${[\\w+\\.\\-:]+})"; |
| |
| util.numericOrContextVarRegexp = function(constraints) |
| { |
| return "^(\\d+)|" + singleContextVarRegexp + "$"; |
| } |
| |
| util.nameOrContextVarRegexp = function(constraints) |
| { |
| return "^(\\w+)|" + singleContextVarRegexp + "$"; |
| } |
| |
| util.jdbcUrlOrContextVarRegexp = function(constraints) |
| { |
| return "^(jdbc:.*:.*)|" + singleContextVarRegexp + "$"; |
| } |
| |
| util.nodeAddressOrContextVarRegexp = function(constraints) |
| { |
| return "^(([0-9a-zA-Z.-_]|::)+:[0-9]{1,5})|" + singleContextVarRegexp + "$"; |
| } |
| |
| util.resizeContentAreaAndRepositionDialog = function(contentNode, dialog) |
| { |
| var viewport = w.getBox(); |
| var contentDimension =dojo.position(contentNode); |
| var dialogDimension = dojo.position(dialog.domNode); |
| var dialogTitleAndFooterHeight = dialogDimension.h - contentDimension.h; |
| var dialogLeftRightSpaces = dialogDimension.w - contentDimension.w; |
| |
| var resize = function() |
| { |
| var viewport = w.getBox(); |
| var width = viewport.w * dialog.maxRatio; |
| var height = viewport.h * dialog.maxRatio; |
| var dialogDimension = dojo.position(dialog.domNode); |
| |
| var maxContentHeight = height - dialogTitleAndFooterHeight; |
| |
| // if width style is set on a dialog node, use dialog width |
| if (dialog.domNode.style && dialog.domNode.style.width) |
| { |
| width = dialogDimension.w; |
| } |
| var maxContentWidth = width - dialogLeftRightSpaces; |
| domStyle.set(contentNode, {"overflow": "auto", maxHeight: maxContentHeight + "px", maxWidth: maxContentWidth + "px"}); |
| |
| var dialogX = viewport.w/2 - dialogDimension.w/2; |
| var dialogY = viewport.h/2 - dialogDimension.h/2; |
| domStyle.set(dialog.domNode, {top: dialogY + "px", left: dialogX + "px"}); |
| dialog.resize(); |
| }; |
| resize(); |
| on(window, "resize", resize); |
| } |
| |
| return util; |
| }); |