You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2016/07/02 20:47:11 UTC

svn commit: r1751095 - in /qpid/java/trunk/broker-plugins/management-http/src/main/java/resources: ./ js/qpid/common/ js/qpid/management/ js/qpid/management/query/ query/

Author: orudyy
Date: Sat Jul  2 20:47:11 2016
New Revision: 1751095

URL: http://svn.apache.org/viewvc?rev=1751095&view=rev
Log:
QPID-7248: Add query browser and functionality to open existing queries from query browser

Added:
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryBrowserTab.js
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryBrowserWidget.js
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/StoreUpdater.js
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryBrowserWidget.html
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showQueryBrowserTab.html
Modified:
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/index.html
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ConsoleHelper.js
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Management.js
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryGrid.js
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryStore.js
    qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js

Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/index.html
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/index.html?rev=1751095&r1=1751094&r2=1751095&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/index.html (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/index.html Sat Jul  2 20:47:11 2016
@@ -125,7 +125,7 @@
                     <div data-dojo-type="dijit/MenuItem"
                       data-dojo-props="onClick: function(e){qpidManagementHelper.showQueryCreateDialog(e);}">Create</div>
                       <div data-dojo-type="dijit/MenuItem"
-                             data-dojo-props="onClick: function(e){qpidManagementHelper.showQueryOpenDialog(e);}">Open</div>
+                             data-dojo-props="onClick: function(e){qpidManagementHelper.showQueryBrowser(e);}">Open</div>
                 </div>
             </div>
             <div data-dojo-type="dijit/form/DropDownButton" data-dojo-props="iconClass: 'helpIcon', showLabel: false">

Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ConsoleHelper.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ConsoleHelper.js?rev=1751095&r1=1751094&r2=1751095&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ConsoleHelper.js (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ConsoleHelper.js Sat Jul  2 20:47:11 2016
@@ -121,7 +121,7 @@ define(["dojo/query",
                             queryCreateDialogForm.on("create", function (e)
                             {
                                 queryCreateDialog.hide();
-                                controller.show("queryTab", e.preference, e.parentObject);
+                                controller.show("query", e.preference, e.parentObject);
                             });
                             queryCreateDialogForm.on("cancel", function (e)
                             {
@@ -143,9 +143,9 @@ define(["dojo/query",
                 });
             }
         },
-        showQueryOpenDialog: function (e)
+        showQueryBrowser: function (e)
         {
-
+            this.controller.show("queryBrowser", "QueueBrowser");
         },
         init: function (controller, treeView)
         {

Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Management.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Management.js?rev=1751095&r1=1751094&r2=1751095&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Management.js (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Management.js Sat Jul  2 20:47:11 2016
@@ -634,23 +634,36 @@ define(["dojo/_base/lang",
         };
 
 
-        Management.prototype.loadPreference = function(parentObject, type, name)
+        Management.prototype.getPreference = function(parentObject, type, name)
         {
            var url =  this.buildPreferenceUrl(parentObject, type, name);
            return this.get({url: url});
         };
 
+        Management.prototype.getUserPreferences = function(parentObject, type)
+        {
+            var url =  this.buildPreferenceUrl(parentObject, type);
+            return this.get({url: url});
+        };
+
+        Management.prototype.getVisiblePreferences = function(parentObject, type)
+        {
+            var url =  this.buildPreferenceUrl(parentObject, type, null, true);
+            return this.get({url: url});
+        };
+
         Management.prototype.deletePreference = function(parentObject, type, name)
         {
            var url =  this.buildPreferenceUrl(parentObject, type, name);
            return this.del({url: url});
         };
 
-        Management.prototype.buildPreferenceUrl = function (parentObject, type, name)
+        Management.prototype.buildPreferenceUrl = function (parentObject, type, name, visiblePreferences)
         {
-            return this.objectToURL(parentObject) + "/userpreferences/"
-                                       + encodeURIComponent(encodeURIComponent(type))
-                                       + "/" + encodeURIComponent(encodeURIComponent(name));
+            return this.objectToURL(parentObject)
+                   + (visiblePreferences ? "/visiblepreferences/" : "/userpreferences/")
+                   + encodeURIComponent(encodeURIComponent(type))
+                   + (name ? "/" + encodeURIComponent(encodeURIComponent(name)) : "" );
         };
 
         return Management;

Added: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryBrowserTab.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryBrowserTab.js?rev=1751095&view=auto
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryBrowserTab.js (added)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryBrowserTab.js Sat Jul  2 20:47:11 2016
@@ -0,0 +1,93 @@
+/*
+ * 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/parser",
+        "dojo/query",
+        "dojo/text!showQueryBrowserTab.html",
+        "qpid/management/query/QueryBrowserWidget",
+        "qpid/common/updater",
+        "dojo/domReady!"],
+    function (parser, query, template, QueryBrowserWidget, updater)
+    {
+        function QueryBrowserTab(name, parent, controller)
+        {
+            this.controller = controller;
+            this.management = controller.management;
+        }
+
+        QueryBrowserTab.prototype.getTitle = function (changed)
+        {
+            return "Query Browser";
+        };
+
+        QueryBrowserTab.prototype.open = function (contentPane)
+        {
+            var that = this;
+            this.contentPane = contentPane;
+            contentPane.containerNode.innerHTML = template;
+            parser.parse(contentPane.containerNode)
+                .then(function (instances)
+                {
+                    that.onOpen(contentPane.containerNode)
+                }, function (e)
+                {
+                    console.error("Unexpected error on parsing query tab template", e);
+                });
+        };
+
+        QueryBrowserTab.prototype.onOpen = function (containerNode)
+        {
+            var that = this;
+            var queryBrowserWidgetNode = query(".queryBrowserWidgetNode", containerNode)[0];
+            this.queryBrowserWidget = new QueryBrowserWidget({management: this.management}, queryBrowserWidgetNode);
+            this.queryBrowserWidget.on("openQuery",
+                function (event)
+                {
+                    that.controller.show("query", event.preference, event.parentObject, event.preference.id);
+                });
+            this.queryBrowserWidget.startup();
+
+            this.contentPane.on("show",
+                function ()
+                {
+                    that.queryBrowserWidget.resize();
+                });
+            updater.add(this.queryBrowserWidget);
+        };
+
+        QueryBrowserTab.prototype.close = function ()
+        {
+            updater.remove(this.queryBrowserWidget);
+            if (this.queryBrowserWidget)
+            {
+                this.queryBrowserWidget.destroyRecursive();
+                this.queryBrowserWidget = null;
+            }
+        };
+
+        QueryBrowserTab.prototype.destroy = function ()
+        {
+            this.close();
+            this.contentPane.onClose();
+            this.controller.tabContainer.removeChild(this.contentPane);
+            this.contentPane.destroyRecursive();
+        };
+
+        return QueryBrowserTab;
+    });

Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js?rev=1751095&r1=1751094&r2=1751095&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/QueryTab.js Sat Jul  2 20:47:11 2016
@@ -20,16 +20,12 @@
  */
 define(["dojo/parser",
         "dojo/query",
-        "dijit/registry",
-        "dojox/html/entities",
-        "qpid/common/properties",
+        "dojo/json",
         "qpid/common/util",
-        "qpid/common/formatter",
         "dojo/text!showQueryTab.html",
         "qpid/management/query/QueryWidget",
-        "dojo/dom-construct",
         "dojo/domReady!"],
-    function (parser, query, registry, entities, properties, util, formatter, template, QueryWidget, domConstruct)
+    function (parser, query, json, util, template, QueryWidget)
     {
         function getPath(parentObject)
         {
@@ -95,13 +91,17 @@ define(["dojo/parser",
             var that = this;
             this.queryWidget.on("save", function(e)
             {
+                if (that.preference.name != e.preference.name)
+                {
+                    that.controller.update(that, e.preference.name, that.parent, e.preference.id);
+                }
                 that.preference = e.preference;
                 var title = that.getTitle();
                 that.contentPane.set("title", title);
             });
             this.queryWidget.on("change", function(e)
             {
-                var changed = !util.equals(this.preference, e.preference);
+                var changed = !util.equals(that.preference, e.preference);
                 var title = that.getTitle(changed);
                 that.contentPane.set("title", title);
             });
@@ -109,12 +109,20 @@ define(["dojo/parser",
             {
                 that.destroy();
             });
+            this.queryWidget.on("clone", function(e)
+            {
+                that.controller.show("query", e.preference, e.parentObject);
+            });
             this.queryWidget.startup();
         };
 
         QueryTab.prototype.close = function ()
         {
-
+            if (this.queryWidget != null)
+            {
+                this.queryWidget.destroyRecursive();
+                this.queryWidget = null;
+            }
         };
 
         QueryTab.prototype.destroy = function ()
@@ -122,7 +130,6 @@ define(["dojo/parser",
             this.close();
             this.contentPane.onClose();
             this.controller.tabContainer.removeChild(this.contentPane);
-            this.queryWidget.destroyRecursive();
             this.contentPane.destroyRecursive();
         };
 

Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js?rev=1751095&r1=1751094&r2=1751095&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js Sat Jul  2 20:47:11 2016
@@ -41,6 +41,7 @@ define(["dojo/dom",
         "qpid/management/VirtualHostNode",
         "qpid/management/Logger",
         "qpid/management/QueryTab",
+        "qpid/management/QueryBrowserTab",
         "dojo/ready",
         "dojox/uuid/generateRandomUuid",
         "dojo/domReady!"],
@@ -67,6 +68,7 @@ define(["dojo/dom",
               VirtualHostNode,
               Logger,
               QueryTab,
+              QueryBrowserTab,
               ready)
     {
         var controller = {};
@@ -89,7 +91,8 @@ define(["dojo/dom",
             virtualhostnode: VirtualHostNode,
             brokerlogger: Logger,
             virtualhostlogger: Logger,
-            queryTab: QueryTab
+            query: QueryTab,
+            queryBrowser: QueryBrowserTab
         };
 
         ready(function ()
@@ -102,27 +105,44 @@ define(["dojo/dom",
 
         controller.viewedObjects = {};
 
-        // TODO: find a better way how to pass business object into a tab instead of passing it as a name
-        controller.show = function (objType, name, parent, objectId)
+        var generateName = function (obj)
         {
-
-            function generateName(obj)
+            if (obj)
             {
-                if (obj)
+                var name = obj.type + (obj.type == "broker" ? "" : ":" + obj.name);
+                if (obj.parent)
                 {
-                    var name = obj.type + (obj.type == "broker" ? "" : ":" + obj.name);
-                    if (obj.parent)
-                    {
-                        name = generateName(obj.parent) + "/" + name;
-                    }
-                    return name;
+                    name = generateName(obj.parent) + "/" + name;
                 }
-                return "";
+                return name;
+            }
+            return "";
+        };
+
+        var generateTabObjId = function(objType, name, parent)
+        {
+            var parentPart = (parent ? generateName(parent) + "/" : "");
+            var namePart = null;
+            if (typeof name === 'string')
+            {
+                namePart = name;
+            }
+            else if (name &&  typeof name === 'object' && name.hasOwnProperty("name"))
+            {
+                namePart = name.name;
+            }
+            else
+            {
+                namePart = "new-" + dojox.uuid.generateRandomUuid();
             }
+            return parentPart + objType + ":" + namePart;
+        };
 
+        // TODO: find a better way how to pass business object into a tab instead of passing it as a name
+        controller.show = function (objType, nameOrObject, parent, objectId)
+        {
             var that = this;
-            var objId = (parent ? generateName(parent) + "/" : "") + objType + ":" +
-                         (name &&  typeof name === 'string' ? name : "-" + dojox.uuid.generateRandomUuid());
+            var objId = generateTabObjId(objType, nameOrObject, parent);
 
             var obj = this.viewedObjects[objId];
             if (obj)
@@ -134,7 +154,8 @@ define(["dojo/dom",
                 var Constructor = constructors[objType];
                 if (Constructor)
                 {
-                    obj = new Constructor(name, parent, this);
+                    obj = new Constructor(nameOrObject, parent, this);
+                    obj.tabId = objId;
                     obj.tabData = {
                         objectId: objectId,
                         objectType: objType
@@ -148,13 +169,13 @@ define(["dojo/dom",
                         onClose: function ()
                         {
                             obj.close();
-                            delete that.viewedObjects[objId];
+                            delete that.viewedObjects[obj.tabId];
                             return true;
                         }
                     });
                     this.tabContainer.addChild(contentPane);
                     var userPreferences = this.management.userPreferences;
-                    if (objType != "broker" && name &&  typeof name === 'string')
+                    if (objType != "broker" && nameOrObject &&  typeof nameOrObject === 'string')
                     {
                         var preferencesCheckBox = new dijit.form.CheckBox({
                             checked: userPreferences.isTabStored(obj.tabData),
@@ -190,7 +211,18 @@ define(["dojo/dom",
         controller.init = function (management)
         {
             controller.management = management;
-        }
+        };
+
+        controller.update = function(tabObject, name, parent, objectId)
+        {
+            var objType = tabObject.tabData.objectType;
+            var tabId = tabObject.tabId;
+            delete this.viewedObjects[tabId];
+            var newTabId = generateTabObjId(objType, name, parent);
+            this.viewedObjects[newTabId] = tabObject;
+            tabObject.tabData.objectId = objectId;
+            tabObject.tabId = newTabId;
+        };
 
         return controller;
     });

Added: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryBrowserWidget.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryBrowserWidget.js?rev=1751095&view=auto
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryBrowserWidget.js (added)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryBrowserWidget.js Sat Jul  2 20:47:11 2016
@@ -0,0 +1,266 @@
+/*
+ * 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/declare",
+        "dojo/_base/lang",
+        "dojo/json",
+        "dojo/Evented",
+        "dojo/Deferred",
+        "dojo/promise/all",
+        'dstore/Store',
+        'dstore/QueryResults',
+        "dstore/Memory",
+        "dstore/Trackable",
+        "dstore/Tree",
+        "dgrid/OnDemandGrid",
+        "dgrid/Keyboard",
+        "dgrid/Selection",
+        "dgrid/Tree",
+        "dgrid/extensions/DijitRegistry",
+        "dgrid/extensions/ColumnResizer",
+        "qpid/management/query/StoreUpdater",
+        "dojo/text!query/QueryBrowserWidget.html",
+        "dijit/_WidgetBase",
+        "dijit/_TemplatedMixin",
+        "dijit/_WidgetsInTemplateMixin",
+        "dijit/form/Button",
+        "dijit/Toolbar",
+        "dijit/Dialog"],
+    function (declare,
+              lang,
+              json,
+              Evented,
+              Deferred,
+              all,
+              Store,
+              QueryResults,
+              Memory,
+              Trackable,
+              TreeStoreMixin,
+              OnDemandGrid,
+              Keyboard,
+              Selection,
+              Tree,
+              DijitRegistry,
+              ColumnResizer,
+              StoreUpdater,
+              template)
+    {
+        var empty = new Deferred();
+        empty.resolve([]);
+
+        var PreferencesStore = declare("qpid.management.query.PreferencesStore",
+            [Store],
+            {
+                management: null,
+                transformer: null,
+                filter: "all",
+                fetch: function ()
+                {
+                    var filter = this.filter;
+                    var userPreferencesPromise = filter === "all" || filter === "myQueries"
+                        ? this.management.getUserPreferences({type: "broker"}, "query")
+                        : empty.promise;
+                    var visiblePreferencesPromise = filter === "all" || filter === "sharedWithMe"
+                        ? this.management.getVisiblePreferences({type: "broker"}, "query")
+                        : empty.promise;
+
+                    var deferred = new Deferred();
+
+                    var successHandler = lang.hitch(this, function (allPreferences)
+                    {
+                        var items = [];
+                        for (var i = 0; i < allPreferences.length; i++)
+                        {
+                            var prefs = allPreferences[i];
+                            for (var j = 0; j < prefs.length; j++)
+                            {
+                                items.push(prefs[j]);
+                                prefs[j].visible = (i === 1);
+                            }
+                        }
+                        if (this.transformer)
+                        {
+                            items = this.transformer(items);
+                        }
+                        deferred.resolve(items);
+                    });
+                    var failureHandler = lang.hitch(this, function (error)
+                    {
+                        if (error && (!error.hasOwnProperty("response") || error.response.hasOwnProperty("status")))
+                        {
+                            this.management.errorHandler(error);
+                        }
+                        deferred.resolve([]);
+                    });
+
+                    all([userPreferencesPromise, visiblePreferencesPromise]).then(successHandler, failureHandler);
+
+                    return new QueryResults(deferred.promise, {
+                        totalLength: deferred.promise.then(function (data)
+                        {
+                            return data.length;
+                        }, function ()
+                        {
+                            return 0;
+                        })
+                    });
+
+                },
+                fetchRange: function ()
+                {
+                    throw new Error("unsupported");
+                }
+            });
+
+        return declare("qpid.management.query.QueryBrowserWidget",
+            [dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin, Evented],
+            {
+                //Strip out the apache comment header from the template html as comments unsupported.
+                templateString: template.replace(/<!--[\s\S]*?-->/g, ""),
+                // attached automatically from template fields
+                queryBrowserGridNode: null,
+                all: null,
+                myQueries: null,
+                sharedWithMe: null,
+
+                // passed automatically by constructor
+                manangement: null,
+
+                // internal
+                _preferenceStore: null,
+                _gridStore: null,
+                queryBrowserGrid: null,
+
+                postCreate: function ()
+                {
+                    this.inherited(arguments);
+                    this._gridStore = new (declare([Memory, TreeStoreMixin, Trackable]))();
+                    this._preferenceStore  = this._createPreferencesStore(this._gridStore);
+                    this._buildGrid();
+                    this._initFilter();
+                },
+                startup: function ()
+                {
+                    this.inherited(arguments);
+                    this.queryBrowserGrid.startup();
+                    this.update();
+                },
+                _buildGrid: function ()
+                {
+                    var columns = {
+                        name: {label: "Query", renderExpando: true, sortable: false},
+                        description: {label: "Description", sortable: false},
+                        owner: {label: "Owner", sortable: false},
+                        visibilityList: {label: "Shared with", sortable: false}
+                    };
+
+                    var Grid = declare([OnDemandGrid, Keyboard, Selection, Tree, DijitRegistry, ColumnResizer]);
+                    var store = this._gridStore.filter({parent: undefined});
+                    this.queryBrowserGrid = new Grid({
+                        minRowsPerPage: Math.pow(2, 53) - 1,
+                        columns: columns,
+                        collection: store
+                    }, this.queryBrowserGridNode);
+
+                    this.queryBrowserGrid.on('.dgrid-row:dblclick', lang.hitch(this, this._openQuery));
+                    this.queryBrowserGrid.on('.dgrid-row:keypress', lang.hitch(this, function (event)
+                    {
+                        if (event.keyCode === keys.ENTER)
+                        {
+                            this._openQuery(event);
+                        }
+                    }));
+                },
+                resize: function ()
+                {
+                    this.inherited(arguments);
+                    if (this.queryBrowserGrid)
+                    {
+                        this.queryBrowserGrid.resize();
+                    }
+                },
+                update: function ()
+                {
+                    this._preferenceStore.update();
+                },
+                _createPreferencesStore: function (targetStore)
+                {
+                    var UpdatableStore = declare([PreferencesStore, StoreUpdater]);
+                    var preferencesStore = new UpdatableStore({
+                        targetStore: targetStore,
+                        management: this.management,
+                        transformer: function (preferences)
+                        {
+                            var items = [];
+                            var rootItem = {id: "broker", name: "Broker"};
+                            items.push(rootItem);
+                            var rootItemCategories = {};
+                            for (var i = 0; i < preferences.length; i++)
+                            {
+                                var preferenceItem = preferences[i];
+                                var categoryName = preferenceItem.value.category;
+                                var categoryItem = rootItemCategories[categoryName];
+                                if (!categoryItem)
+                                {
+                                    categoryItem = {id: categoryName, name: categoryName, parent: rootItem.id};
+                                    items.push(categoryItem);
+                                    rootItemCategories[categoryName] = categoryItem;
+                                }
+                                preferenceItem.hasChildren = false;
+                                preferenceItem.parent = categoryItem.id;
+                                items.push(preferenceItem);
+                            }
+                            return items;
+                        }
+                    });
+                    return preferencesStore;
+                },
+                _openQuery: function (event)
+                {
+                    var row = this.queryBrowserGrid.row(event);
+                    //TODO: we need the associated object hierarchy path
+                    if (row.data.value)
+                    {
+                        this.emit("openQuery", {preference: row.data, parentObject: {type: "broker"}});
+                    }
+                },
+                _initFilter: function ()
+                {
+                    var that = this;
+                    this.all.on("click", function (e)
+                    {
+                        that._modifyFilter(e, that.all);
+                    });
+                    this.myQueries.on("click", function (e)
+                    {
+                        that._modifyFilter(e, that.myQueries);
+                    });
+                    this.sharedWithMe.on("click", function (e)
+                    {
+                        that._modifyFilter(e, that.sharedWithMe);
+                    });
+                },
+                _modifyFilter: function (event, targetWidget)
+                {
+                    this._preferenceStore.filter = targetWidget.get("value");
+                    this.update();
+                }
+            });
+    });

Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryGrid.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryGrid.js?rev=1751095&r1=1751094&r2=1751095&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryGrid.js (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryGrid.js Sat Jul  2 20:47:11 2016
@@ -32,6 +32,7 @@ define(["dojo/_base/declare",
         "dgrid/extensions/ColumnResizer",
         "dgrid/extensions/DijitRegistry",
         "qpid/management/query/QueryStore",
+        "qpid/management/query/StoreUpdater",
         "dojo/keys",
         "qpid/common/util"],
     function (declare,
@@ -48,43 +49,12 @@ define(["dojo/_base/declare",
               ColumnResizer,
               DijitRegistry,
               QueryStore,
+              StoreUpdater,
               keys,
               util)
     {
 
-        var createIdToIndexMap = function(results, idProperty)
-        {
-            var map = {};
-            for(var i = 0; i < results.length; i++)
-            {
-                var id = results[i][idProperty];
-                map[id] = i;
-            }
-            return map;
-        }
-
-        var updateIdToIndexMap = function(results, idProperty, idToIndexMap, startIndex)
-        {
-            for(var i = startIndex; i < results.length; i++)
-            {
-                 var id = results[i][idProperty];
-                 idToIndexMap[id] = i;
-            }
-        }
-
-        var TrackableQueryStore = declare(QueryStore,
-            {
-                /*
-                 adding method track
-                 enables tracking of add, update and delete events
-                 */
-                track: function ()
-                {
-                    return this;
-                }
-            });
-
-        var QueryGrid = declare("qpid.management.query.QueryGrid",
+        return declare("qpid.management.query.QueryGrid",
             [Grid, Keyboard, Selection, Pagination, DijitRegistry, ColumnResizer],
             {
                 management: null,
@@ -96,7 +66,22 @@ define(["dojo/_base/declare",
 
                 postscript: function (args)
                 {
-                    this._store = !!args.detectChanges ? new TrackableQueryStore(args) : new QueryStore(args);
+                    if (args.detectChanges)
+                    {
+                        var Store = declare([QueryStore, StoreUpdater],
+                            {
+                                track: function ()
+                                {
+                                    return this;
+                                }
+                            });
+                        this._store = new Store(args);
+                        this._store.on("updateCompleted", lang.hitch(this, this._onFetchCompleted));
+                    }
+                    else
+                    {
+                        this._store = new QueryStore(args);
+                    }
 
                     var settings = lang.mixin({
                         collection: this._store,
@@ -113,12 +98,12 @@ define(["dojo/_base/declare",
                 postCreate: function ()
                 {
                     this.inherited(arguments);
-                    this.on('.dgrid-row:dblclick', lang.hitch(this, this._onRowClick));
+                    this.on('.dgrid-row:dblclick', lang.hitch(this, this._openObjectTab));
                     this.on('.dgrid-row:keypress', lang.hitch(this, function (event)
                     {
                         if (event.keyCode === keys.ENTER)
                         {
-                            this._onRowClick(event);
+                            this._openObjectTab(event);
                         }
                     }));
 
@@ -141,46 +126,16 @@ define(["dojo/_base/declare",
                     }));
                     this._store.on('queryCompleted', lang.hitch(this, function (event)
                     {
+                        this._start = event.query.offset;
+                        this._end = event.query.offset + event.query.limit;
                         on.emit(this.domNode, 'queryCompleted', event);
                     }));
-                    this._store.on('fetchCompleted', lang.hitch(this, function (event)
-                    {
-                        this._start = event.start;
-                        this._end = event.end;
-                        if (this.detectChanges)
-                        {
-                            /*
-                             Handle 'fetchCompleted' event
-                             and detect changes in row data.
-                             Emit 'add', 'delete', 'update' events
-                             for changed rows
-                             */
-                            if (this._updatingData)
-                            {
-                                try
-                                {
-                                    this._compareResultsAndEmitEventsOnChanges(event);
-                                }
-                                finally
-                                {
-                                    this._updatingData = false;
-                                }
-                            }
-                            else
-                            {
-                                var results = event.results.slice(0);
-                                this._currentResults = results;
-                                this._currentResultsIdToIndexMap = createIdToIndexMap(results, this._store.idProperty);
-                            }
-                        }
-                    }));
                 },
                 updateData: function ()
                 {
-                    if (this.detectChanges && this._end)
+                    if (this.detectChanges)
                     {
-                        this._updatingData = true;
-                        this._store.fetchRange({start: this._start, end: this._end});
+                        this._store.updateRange();
                     }
                 },
                 setCategory: function (category)
@@ -260,7 +215,7 @@ define(["dojo/_base/declare",
                     this._store.orderBy = orderByExpression;
                     on.emit(this.domNode, "orderByChanged", {orderBy: orderByExpression});
                 },
-                _onRowClick: function (event)
+                _openObjectTab: function (event)
                 {
                     var row = this.row(event);
                     var promise = this.management.get({url: "service/structure"});
@@ -308,86 +263,6 @@ define(["dojo/_base/declare",
                         }
                     }));
                 },
-                _compareResultsAndEmitEventsOnChanges: function (evt)
-                {
-                    var results = evt.results;
-                    if (results)
-                    {
-                        var newResults = results.slice(0);
-                        var store = this._store;
-                        var idProperty = store.idProperty;
-                        var newResultsIdToIndexMap = createIdToIndexMap(newResults, idProperty);
-                        if (this._currentResults)
-                        {
-                            var currentResults = this._currentResults.slice(0);
-                            for (var i = currentResults.length - 1; i >= 0; i--)
-                            {
-                                var currentResult = currentResults[i];
-                                var id = currentResult[idProperty];
-                                var newResultIndex = newResultsIdToIndexMap[id];
-                                if (newResultIndex === undefined)
-                                {
-                                    var event = {"target": currentResult,
-                                                 "previousIndex": evt.start + i,
-                                                 "index": evt.start + i};
-                                    store.emit("delete", event);
-                                    currentResults.splice(i, 1);
-                                    updateIdToIndexMap(currentResults,
-                                                       idProperty,
-                                                       this._currentResultsIdToIndexMap,
-                                                       i);
-                                    delete this._currentResultsIdToIndexMap[id];
-                                }
-                            }
-
-                            for (var j = 0; j < newResults.length; j++)
-                            {
-                                var newResult = newResults[j];
-                                var id = newResult[idProperty];
-                                var previousIndex = this._currentResultsIdToIndexMap[id];
-
-                                if (previousIndex === undefined)
-                                {
-                                    var event = {"target": newResult, "index": j + evt.start};
-                                    store.emit("add", event);
-                                    currentResults.splice(j, 0, newResult);
-                                    updateIdToIndexMap(currentResults,
-                                                       idProperty,
-                                                       this._currentResultsIdToIndexMap,
-                                                       j);
-                                }
-                                else
-                                {
-                                    var currentResult = currentResults[previousIndex];
-                                    var event = {"target": newResult,
-                                                 "previousIndex": previousIndex + evt.start,
-                                                 "index": j + evt.start};
-                                    if (previousIndex === j)
-                                    {
-                                        currentResults[j] = newResult;
-                                        if (!util.equals(newResult, currentResult))
-                                        {
-                                            store.emit("update", event);
-                                        }
-                                    }
-                                    else
-                                    {
-                                        currentResults.splice(previousIndex, 1);
-                                        currentResults.splice(j, 0, currentResult);
-                                        updateIdToIndexMap(currentResults,
-                                                           idProperty,
-                                                           this._currentResultsIdToIndexMap,
-                                                           Math.min(previousIndex, j));
-                                        store.emit("update", event);
-                                    }
-                                }
-                            }
-                        }
-                        this._currentResults = newResults;
-                        this._currentResultsIdToIndexMap = newResultsIdToIndexMap
-                        this._onFetchCompleted(evt)
-                    }
-                },
                 _onFetchCompleted: function (event)
                  {
                     var rowsPerPage = this.rowsPerPage;
@@ -412,5 +287,4 @@ define(["dojo/_base/declare",
                 }
             });
 
-        return QueryGrid;
     });

Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryStore.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryStore.js?rev=1751095&r1=1751094&r2=1751095&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryStore.js (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryStore.js Sat Jul  2 20:47:11 2016
@@ -48,20 +48,7 @@ function (lang, declare, Evented, json,
 
         fetchRange: function (kwArgs)
         {
-            var queryResults = this._request(kwArgs);
-            all({results: queryResults, totalLength: queryResults.totalLength})
-                .then(lang.hitch(this,
-                    function (data)
-                    {
-                        this.emit("fetchCompleted",
-                            {
-                                start: kwArgs.start,
-                                end: kwArgs.end,
-                                results: data.results,
-                                totalLength: data.totalLength
-                            });
-                    }));
-            return queryResults;
+            return this._request(kwArgs);
         },
 
         _request: function (kwArgs)
@@ -71,6 +58,31 @@ function (lang, declare, Evented, json,
                 return this._createQueryResults(this._lastResponsePromise);
             }
 
+            var query = {
+                category: this.category,
+                select: this.selectClause
+            };
+
+            if (this.where)
+            {
+                query.where = this.where;
+            }
+
+            if (this.orderBy)
+            {
+                query.orderBy = this.orderBy;
+            }
+
+            if (kwArgs && kwArgs.hasOwnProperty("start"))
+            {
+                query.offset = kwArgs.start;
+            }
+
+            if (kwArgs && kwArgs.hasOwnProperty("end"))
+            {
+                query.limit = kwArgs.end - (query.offset ? query.offset : 0);
+            }
+
             if (!this.selectClause)
             {
                 var responseDeferred = new Deferred();
@@ -83,48 +95,28 @@ function (lang, declare, Evented, json,
             }
             else
             {
-                var queryRequest = {
-                    category: this.category,
-                    select: this.selectClause
-                };
-
+                var queryRequest = lang.clone(query);
                 if (this.parentObject)
                 {
                     queryRequest.parent = this.parentObject;
                 }
-
-                if (this.where)
-                {
-                    queryRequest.where = this.where;
-                }
-
-                if ("start" in kwArgs)
-                {
-                    queryRequest.offset = kwArgs.start;
-                }
-
-                if ("end" in kwArgs)
-                {
-                    queryRequest.limit = kwArgs.end - (queryRequest.offset ? queryRequest.offset : 0);
-                }
-
-                if (this.orderBy)
-                {
-                    queryRequest.orderBy = this.orderBy;
-                }
-
                 this._lastResponsePromise = this.management.query(queryRequest);
             }
             this._lastResponsePromise.then(lang.hitch(this, function (data)
             {
-                this.emit("queryCompleted", data);
+                this.emit("queryCompleted", {data: data, query: query, parentObject: this.parentObject});
             }), lang.hitch(this, function (error)
             {
                 this.emit("queryCompleted",
                     {
-                        headers: [],
-                        results: [],
-                        total: 0
+                        data: {
+                            headers: [],
+                            results: [],
+                            total: 0
+                        },
+                        query: query,
+                        parentObject: this.parentObject,
+                        error: error
                     });
             }));
             return this._createQueryResults(this._lastResponsePromise);

Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js?rev=1751095&r1=1751094&r2=1751095&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js Sat Jul  2 20:47:11 2016
@@ -315,7 +315,9 @@ define(["dojo/_base/declare",
                 },
                 _postCreate: function ()
                 {
-                    this.categoryName = this.preference.value.category;
+                    var valuePresent = this.preference && this.preference.value;
+                    var selectPresent = valuePresent && this.preference.value.select;
+                    this.categoryName = valuePresent && this.preference.value.category ? this.preference.value.category : "Queue";
                     this._lastStandardModeSelect = [];
                     this._lastHeaders = [];
 
@@ -356,12 +358,14 @@ define(["dojo/_base/declare",
                     this.standardSearchButton.on("click", lang.hitch(this, this.search));
                     this.modeButton.on("click", lang.hitch(this, this._showModeSwitchWarningIfRequired));
 
-                    this._buildGrid();
+                    var rowsPerPage = valuePresent && this.preference.value.limit ? this.preference.value.limit  : 100;
+                    var currentPage = valuePresent && this.preference.value.offset ?  this.preference.value.offset/rowsPerPage + 1: 1;
+                    this._buildGrid(currentPage, rowsPerPage);
                     var openingPreference = this.preference && this.preference.value && this.preference.value.select;
                     this._initCategory(this.categoryName, !openingPreference);
                     this._toggleSearchButton();
 
-                    if (openingPreference)
+                    if (selectPresent)
                     {
                         this._modeChanged();
                         this.advancedSelect.set("value", this.preference.value.select);
@@ -523,13 +527,11 @@ define(["dojo/_base/declare",
                     this._setSelectClause(selectClause);
                     this._lastStandardModeSelect = lang.clone(selectedColumns);
                     this._toggleSearchButton(selectClause);
-                    this._queryChanged();
                 },
                 _standardModeSelectChanged: function (selectedColumns)
                 {
                     this._processStandardModeSelectChange(selectedColumns);
                     this.search();
-                    this._queryChanged();
                 },
                 _standardModeColumnOrderChanged: function (event)
                 {
@@ -545,7 +547,6 @@ define(["dojo/_base/declare",
                         }
                         this._processStandardModeSelectChange(newSelectedItems);
                         this.standardSelectChooser.set("data", {"selected": newSelectedItems});
-                        this._queryChanged();
                     }
                     else
                     {
@@ -572,7 +573,6 @@ define(["dojo/_base/declare",
                             this._processStandardModeSelectChange(newSelectedItems);
                             this.standardSelectChooser.set("data", {"selected": newSelectedItems});
                             this._resultsGrid.refresh();
-                            this._queryChanged();
                         }
                         finally
                         {
@@ -587,26 +587,32 @@ define(["dojo/_base/declare",
                 {
                     this._resultsGrid.setWhere(result);
                     this.search();
-                    this._queryChanged();
                 },
-                _buildGrid: function ()
+                _buildGrid: function (currentPage, rowsPerPage)
                 {
-                    var openingPreference = this.preference && this.preference.value && this.preference.value.select;
-                    var rowsPerPage = 100, currentPage = 1;
-                    if (openingPreference)
-                    {
-                        rowsPerPage = this.preference.value.limit || 100;
-                        var start = this.preference.value.offset || 0;
-                        currentPage = start/rowsPerPage + 1;
-                    }
-                    var grid = new (declare([QueryGrid, ColumnReorder, ColumnHider]))({
+                    var Grid = declare([QueryGrid, ColumnReorder, ColumnHider],
+                                      {
+                                            _restoreCurrentPage : currentPage > 1,
+                                            gotoPage:function (page)
+                                            {
+                                                if (this._restoreCurrentPage)
+                                                {
+                                                    return this.inherited(arguments, [currentPage]);
+                                                }
+                                                else
+                                                {
+                                                    return this.inherited(arguments);
+                                                }
+                                            }
+                                      });
+                    var grid = new Grid({
                         controller: this.controller,
                         management: this.management,
                         category: this.categoryName.toLowerCase(),
                         parentObject: this.parentObject,
                         zeroBased: false,
                         rowsPerPage: rowsPerPage,
-                        currentPage: currentPage,
+                        _currentPage: currentPage,
                         transformer: function (data)
                         {
                             var dataResults = data.results;
@@ -633,20 +639,24 @@ define(["dojo/_base/declare",
                     {
                         this._resultsGrid.setUseCachedResults(false);
                     }));
-                    grid.on('queryCompleted', lang.hitch(this, this._buildColumnsIfHeadersChanged));
+                    grid.on('queryCompleted', lang.hitch(this, this._queryCompleted));
                     grid.on('orderByChanged', lang.hitch(this, function (event)
                     {
                         this.advancedOrderBy.set("value", event.orderBy);
-                        this._queryChanged();
                     }));
                     grid.on('dgrid-columnreorder', lang.hitch(this, this._standardModeColumnOrderChanged));
                     grid.on('dgrid-columnstatechange', lang.hitch(this, this._standardModeColumnStateChanged));
                     grid.hiderToggleNode.title = "Remove columns";
                     this._resultsGrid = grid;
                 },
-                _buildColumnsIfHeadersChanged: function (event)
+                _queryCompleted: function (e)
+                {
+                    this._buildColumnsIfHeadersChanged(e.data);
+                    this._queryChanged(e.query);
+                },
+                _buildColumnsIfHeadersChanged: function (data)
                 {
-                    var headers = lang.clone(event.headers);
+                    var headers = lang.clone(data.headers);
                     if (headers.length > 0)
                     {
                         headers.pop();
@@ -659,6 +669,7 @@ define(["dojo/_base/declare",
                             this._standardMode && headers.length > 0 ? '' : 'none';
                         this._resultsGrid.set("columns", this._getColumns(headers));
                         this._resultsGrid.resize();
+                        this._resultsGrid._restoreCurrentPage = false;
                     }
                 },
                 _equalStringArrays: function (a, b)
@@ -822,7 +833,6 @@ define(["dojo/_base/declare",
                         this._resultsGrid.setWhere(this.advancedWhere.value);
                         this._resultsGrid.setOrderBy(this.advancedOrderBy.value);
                         this.search();
-                        this._queryChanged();
                     }
                 },
                 _modeChanged: function ()
@@ -878,7 +888,6 @@ define(["dojo/_base/declare",
                         this._toggleSearchButton(select);
                         this._resultsGrid.hiderToggleNode.style.display = '';
                         this.search();
-                        this._queryChanged();
                     }
                 },
                 _getCategoryMetadata: function (value)
@@ -954,10 +963,17 @@ define(["dojo/_base/declare",
                         asObject: columnsObject
                     };
                 },
-                _getQuery: function ()
+                _getQuery: function (queryObject)
                 {
-                    var query = this._resultsGrid.getQuery();
+                    var query = {
+                        where: "",
+                        orderBy: ""
+                    };
+
+                    lang.mixin(query, queryObject || this._resultsGrid.getQuery());
+
                     query.select = this._selectClause;
+                    query.category = this.categoryName;
                     return query;
                 },
                 _saveQuery: function ()
@@ -1048,7 +1064,7 @@ define(["dojo/_base/declare",
                     }
                     preference.value = this._getQuery();
                     this._queryCloneDialog.hide();
-                    this.controller.show("queryTab", preference, e.parentObject);
+                    this.emit("clone", {preference: preference, parentObject: e.parentObject});
                 },
                 _onQueryCloneCancel: function ()
                 {
@@ -1082,12 +1098,11 @@ define(["dojo/_base/declare",
 
                 _loadPreference: function (name)
                 {
-                    return this.management.loadPreference(this.parentObject, "query", name)
+                    return this.management.getPreference(this.parentObject, "query", name)
                 },
-                _queryChanged: function()
+                _queryChanged: function(query)
                 {
-                    var queryParameters = this._getQuery();
-                    var value = this.preference.value;
+                    var queryParameters = this._getQuery(query);
                     var pref = lang.clone(this.preference);
                     pref.value = queryParameters;
                     this.emit("change", {preference: pref});

Added: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/StoreUpdater.js
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/StoreUpdater.js?rev=1751095&view=auto
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/StoreUpdater.js (added)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/StoreUpdater.js Sat Jul  2 20:47:11 2016
@@ -0,0 +1,238 @@
+/*
+ *
+ * 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/declare",
+        "dojo/_base/lang",
+        "dojo/json",
+        "dojo/promise/all",
+        "qpid/common/util"],
+    function (declare, lang, json, all, util)
+    {
+        var createIdToIndexMap = function (results, idProperty)
+        {
+            var map = {};
+            for (var i = 0; i < results.length; i++)
+            {
+                var id = results[i][idProperty];
+                map[id] = i;
+            }
+            return map;
+        };
+
+        var updateIdToIndexMap = function (results, idProperty, idToIndexMap, startIndex)
+        {
+            for (var i = startIndex; i < results.length; i++)
+            {
+                var id = results[i][idProperty];
+                idToIndexMap[id] = i;
+            }
+        };
+
+        return declare(null,
+            {
+                /**
+                 * fields set from constructor parameter object
+                 */
+                targetStore: null,
+
+                /**
+                 * internal fields
+                 */
+                _currentResults: null,
+                _currentResultsIdToIndexMap: null,
+                _updating: false,
+                _fetchRangeCapturedArguments: null,
+
+                fetch: function ()
+                {
+                    var queryResults = this.inherited(arguments);
+                    this._captureResults(queryResults, "fetch");
+                    return queryResults;
+                },
+                fetchRange: function (args)
+                {
+                    var queryResults = this.inherited(arguments);
+                    this._captureResults(queryResults, "fetchRange", args);
+                    return queryResults;
+                },
+                update: function ()
+                {
+                    if (!this._updating)
+                    {
+                        this._updating = true;
+                        this.fetch();
+                    }
+                },
+                updateRange: function ()
+                {
+                    var args = this._fetchRangeCapturedArguments;
+                    if (!this._updating && args)
+                    {
+                        this._updating = true;
+                        this.fetchRange(args);
+                    }
+                },
+                _captureResults: function (queryResults, methodName, args)
+                {
+                    var handler = lang.hitch(this, function (data)
+                    {
+                        this._processResults(data, methodName, args);
+                    });
+                    all({results: queryResults, totalLength: queryResults.totalLength})
+                        .then(handler);
+                },
+                _processResults: function (data, methodName, args)
+                {
+                    var capturedArguments = args ? lang.clone(args) : {};
+                    if (this._updating)
+                    {
+                        try
+                        {
+                            lang.mixin(capturedArguments, data);
+                            this._detectChangesAndNotify(capturedArguments);
+                        }
+                        finally
+                        {
+                            this._updating = false;
+                            this.emit("updateCompleted", capturedArguments);
+                        }
+                    }
+                    else
+                    {
+                        var results = data.results.slice(0);
+                        this._currentResults = results;
+                        this._currentResultsIdToIndexMap = createIdToIndexMap(results, this.idProperty);
+                        this["_" + methodName + "CapturedArguments"] = capturedArguments;
+                    }
+                },
+                _detectChangesAndNotify: function (data)
+                {
+                    var results = data.results;
+                    var offset = data.start || 0;
+                    if (results)
+                    {
+                        var newResults = results.slice(0);
+                        var idProperty = this.idProperty;
+                        var newResultsIdToIndexMap = createIdToIndexMap(newResults, idProperty);
+                        if (this._currentResults)
+                        {
+                            var currentResults = this._currentResults.slice(0);
+                            for (var i = currentResults.length - 1; i >= 0; i--)
+                            {
+                                var currentResult = currentResults[i];
+                                var id = currentResult[idProperty];
+                                var newResultIndex = newResultsIdToIndexMap[id];
+                                if (newResultIndex === undefined)
+                                {
+                                    this._pushChange("delete", currentResult, offset + i, offset + i);
+                                    currentResults.splice(i, 1);
+                                    updateIdToIndexMap(currentResults,
+                                        idProperty,
+                                        this._currentResultsIdToIndexMap,
+                                        i);
+                                    delete this._currentResultsIdToIndexMap[id];
+                                }
+                            }
+
+                            for (var j = 0; j < newResults.length; j++)
+                            {
+                                var newResult = newResults[j];
+                                var id = newResult[idProperty];
+                                var previousIndex = this._currentResultsIdToIndexMap[id];
+
+                                if (previousIndex === undefined)
+                                {
+                                    currentResults.splice(j, 0, newResult);
+                                    updateIdToIndexMap(currentResults,
+                                        idProperty,
+                                        this._currentResultsIdToIndexMap,
+                                        j);
+                                    this._pushChange("add", newResult, offset + j);
+                                }
+                                else
+                                {
+                                    var currentResult = currentResults[previousIndex];
+                                    if (previousIndex === j)
+                                    {
+                                        currentResults[j] = newResult;
+                                        if (!util.equals(newResult, currentResult))
+                                        {
+                                            this._pushChange("update", newResult, offset + j, previousIndex + offset);
+                                        }
+                                    }
+                                    else
+                                    {
+                                        this._pushChange("update", newResult, offset + j, previousIndex + offset);
+                                        currentResults.splice(previousIndex, 1);
+                                        currentResults.splice(j, 0, currentResult);
+                                        updateIdToIndexMap(currentResults,
+                                            idProperty,
+                                            this._currentResultsIdToIndexMap,
+                                            Math.min(previousIndex, j));
+                                    }
+                                }
+                            }
+                        }
+                        else
+                        {
+                            for (var j = 0; j < newResults.length; j++)
+                            {
+                                this._pushChange("add", newResults[j], offset + j);
+                            }
+                        }
+
+                        this._currentResults = newResults;
+                        this._currentResultsIdToIndexMap = newResultsIdToIndexMap;
+                    }
+                },
+                _pushChange: function (change, item, currentIndex, previousIndex)
+                {
+                    if (this.targetStore)
+                    {
+                        if (change === "update")
+                        {
+                            this.targetStore.put(item);
+                        }
+                        else if (change === "add")
+                        {
+                            this.targetStore.add(item);
+                        }
+                        else if (change === "delete")
+                        {
+                            this.targetStore.remove(item.id);
+                        }
+                        else
+                        {
+                            throw new Error("Change " + change + " is unknown by the store");
+                        }
+                    }
+                    else
+                    {
+                        var event = {
+                            "target": item,
+                            "index": currentIndex,
+                            "previousIndex": previousIndex
+                        };
+                        this.emit(change, event);
+                    }
+                }
+            });
+    });
\ No newline at end of file

Added: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryBrowserWidget.html
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryBrowserWidget.html?rev=1751095&view=auto
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryBrowserWidget.html (added)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryBrowserWidget.html Sat Jul  2 20:47:11 2016
@@ -0,0 +1,30 @@
+<!--
+  ~ 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.
+  ~
+  -->
+
+<div>
+
+    <div data-dojo-type="dijit/Toolbar">
+        <input type="radio" data-dojo-type="dijit/form/RadioButton" data-dojo-attach-point="all" name="filter" checked="true" value="all">All</input>
+        <input type="radio" data-dojo-type="dijit/form/RadioButton" data-dojo-attach-point="myQueries"  name="filter" value="myQueries">My Queries</input>
+        <input type="radio" data-dojo-type="dijit/form/RadioButton" data-dojo-attach-point="sharedWithMe"  name="filter" value="sharedWithMe">Shared with me</input>
+    </div>
+
+    <div data-dojo-attach-point="queryBrowserGridNode"/>
+</div>
\ No newline at end of file

Added: qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showQueryBrowserTab.html
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showQueryBrowserTab.html?rev=1751095&view=auto
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showQueryBrowserTab.html (added)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/showQueryBrowserTab.html Sat Jul  2 20:47:11 2016
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  ~
+  -->
+<div class="query">
+    <div id='grid' class="queryBrowserWidgetNode"></div>
+</div>
+



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org