blob: 8da0bafd066f3d201b9a216c3262c02a0aefb239 [file] [log] [blame]
/*
*
* 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;
});