Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/DropDownSelect.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/DropDownSelect.js?rev=1741469&r1=1741468&r2=1741469&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/DropDownSelect.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/DropDownSelect.js
 Thu Apr 28 16:22:56 2016
@@ -119,6 +119,7 @@ function(declare, lang, array, json, dom
                         */
                        _optionsGrid: null,
                        _descending: false,
+                       _selectedItems: [],
 
                        postCreate:  function()
                                     {
@@ -162,12 +163,36 @@ function(declare, lang, array, json, dom
                                                                  
deselectOnRefresh: false
                                                                },
                                                                
this.optionsGrid);
-                                      grid.on('dgrid-select', lang.hitch(this, 
this._selectionChanged));
-                                      grid.on('dgrid-deselect', 
lang.hitch(this, this._selectionChanged));
+                                      grid.on('dgrid-select', lang.hitch(this, 
this._gridSelected));
+                                      grid.on('dgrid-deselect', 
lang.hitch(this, this._gridDeselected));
                                       grid.on('dgrid-sort', lang.hitch(this, 
function(event){this._descending = event.sort[0].descending}));
                                       grid.setTotal(this.items ? 
this.items.length : 0);
                                       this._optionsGrid =  grid;
                                    },
+                       _gridSelected: function(event)
+                                   {
+                                     for (var i = 0; i < event.rows.length; 
++i)
+                                     {
+                                         
this._selectedItems.push(event.rows[i].data);
+                                     }
+                                     this._selectionChanged();
+                                   },
+                       _gridDeselected: function(event)
+                                   {
+                                       for (var i = 0; i < event.rows.length; 
++i)
+                                       {
+                                           var id = event.rows[i].id;
+                                           for (var j = 0; j < 
this._selectedItems.length; ++j)
+                                           {
+                                               if (this._selectedItems[j].id 
=== id)
+                                               {
+                                                   
this._selectedItems.splice(j, 1);
+                                                   break;
+                                               }
+                                           }
+                                       }
+                                       this._selectionChanged();
+                                   },
                        _setDataAttr:function(data)
                                     {
                                       if (data.idProperty)
@@ -181,11 +206,7 @@ function(declare, lang, array, json, dom
                                       }
 
                                       var store;
-                                      if (data.store)
-                                      {
-                                        store = data.store;
-                                      }
-                                      else if (data.items)
+                                      if (data.items)
                                       {
                                         store = new Memory({data: data.items, 
idProperty: this.idProperty});
                                         this.items = data.items;
@@ -206,32 +227,56 @@ function(declare, lang, array, json, dom
                                           this._selectGrid(data.selected);
                                       }
                                     },
+                       _findItemById: function(items, idValue)
+                                    {
+                                        for (var i = 0; i < items.length; ++i)
+                                        {
+                                            if (items[i][this.idProperty] === 
idValue)
+                                            {
+                                                return items[i];
+                                            }
+                                        }
+                                        return null;
+                                    },
                        _selectGrid: function(selected)
                                     {
-                                      var selectedRowIds = 
lang.clone(this._optionsGrid.selection || {});
-                                      if (selected && selected.length && 
this.store)
-                                      {
-                                        for(var i=0;i<selected.length;i++)
+                                        var items = [];
+                                        if (selected && selected.length && 
!selected[0].hasOwnProperty(this.idProperty))
                                         {
-                                          var id = selected[i] && 
selected[i].hasOwnProperty(this.idProperty) ? selected[i][this.idProperty] : 
selected[i];
-                                          if (id in selectedRowIds)
-                                          {
-                                            delete selectedRowIds[id];
-                                          }
-                                          else
-                                          {
-                                            this._optionsGrid.select(id, null, 
true);
-                                          }
+                                            for (var i = 0; i < 
selected.length; ++i)
+                                            {
+                                                var item = 
this._findItemById(this.items, selected[i]);
+                                                if (item)
+                                                {
+                                                    items.push(item);
+                                                }
+                                            }
+                                        }
+                                        else
+                                        {
+                                            items = lang.clone(selected);
                                         }
-                                      }
 
-                                      for (var id in selectedRowIds)
-                                      {
-                                        if (this._optionsGrid.selection[id])
+                                        var selectedItems = 
lang.clone(this._selectedItems);
+                                        for (var i = 0; i < 
selectedItems.length; ++i)
                                         {
-                                           this._optionsGrid.select(id, null, 
false);
+                                            var currentItem = selectedItems[i];
+                                            var item = 
this._findItemById(items, currentItem[this.idProperty]);
+                                            if (!item)
+                                            {
+                                                
this._optionsGrid.deselect(currentItem);
+                                            }
                                         }
-                                      }
+                                        for (var i = 0; i < items.length; ++i)
+                                        {
+                                            var currentItem = items[i];
+                                            var item = 
this._findItemById(this._selectedItems, currentItem[this.idProperty]);
+                                            if (!item)
+                                            {
+                                                
this._optionsGrid.select(currentItem);
+                                            }
+                                        }
+                                        this._selectedItems = items;
                                     },
                        _onClear:    function()
                                     {
@@ -262,7 +307,7 @@ function(declare, lang, array, json, dom
                                     },
                        _selectionChanged: function(event)
                                     {
-                                      this.doneButton.set("disabled", 
!this._isSelected());
+                                      this.doneButton.set("disabled", 
this._selectedItems.length === 0);
                                     },
                        _getOptionColumns: function()
                                     {
@@ -270,42 +315,18 @@ function(declare, lang, array, json, dom
                                       columns[this.nameProperty] = { 
label:"Name", sortable: true }
                                       return columns;
                                     },
-                       _isSelected: function()
-                                    {
-                                      var selectionFound = false;
-                                      for (var id in 
this._optionsGrid.selection)
-                                      {
-                                          if (this._optionsGrid.selection[id])
-                                          {
-                                             selectionFound = true;
-                                             break;
-                                          }
-                                      }
-                                      return selectionFound;
-                                    },
                        _getSelectedItemsAttr: function()
                                     {
-                                      var selected = [];
-                                      if (this.store && 
this._optionsGrid.selection)
-                                      {
-                                        for (var id in 
this._optionsGrid.selection)
-                                        {
-                                          if (this._optionsGrid.selection[id])
-                                          {
-                                            selected.push(id);
-                                          }
-                                        }
-                                      }
-                                      var filter = new 
this.store.Filter().in(this.idProperty, selected);
-                                      var promise = 
this.store.filter(filter).fetch();
-                                      return promise;
+                                      return lang.clone(this._selectedItems);
                                     },
                        _reset:      function(items)
                                     {
                                       this._onClear();
 
-                                      items = items || [];
-                                      this._selectGrid(items);
+                                      if (items)
+                                      {
+                                          this._selectGrid(items);
+                                      }
                                     }
                    });
 
@@ -344,13 +365,7 @@ function(declare, lang, array, json, dom
                        _setDataAttr:function(data)
                                     {
                                       this._optionsPanel.set("data", data);
-                                      var promise = 
this._optionsPanel.get("selectedItems");
-                                      dojo.when(promise,
-                                                lang.hitch(this,
-                                                           
function(selectedItems)
-                                                           {
-                                                             
this._selectedItems = selectedItems;
-                                                           }));
+                                      this._selectedItems = 
this._optionsPanel.get("selectedItems");
                                     },
                        _getSelectedItemsAttr: function()
                                     {
@@ -358,13 +373,10 @@ function(declare, lang, array, json, dom
                                     },
                        _onSelectionDone: function()
                                     {
-                                      var promise = 
this._optionsPanel.get("selectedItems");
-                                      dojo.when(promise, lang.hitch(this, 
function(selectedItems)
-                                                                          {
-                                                                            
this._selectedItems = selectedItems;
-                                                                            
this._hideAndResetSearch(selectedItems);
-                                                                            
this.emit("change", selectedItems);
-                                                                          }));
+                                      this._selectedItems = 
this._optionsPanel.get("selectedItems");
+                                      popup.close(this._optionsDialog);
+                                      this._optionsPanel._reset();
+                                      this.emit("change", this._selectedItems);
                                     },
                        _hideAndResetSearch: function()
                                     {
@@ -375,11 +387,11 @@ function(declare, lang, array, json, dom
                                     {
                                       
this._optionsPanel._reset(this._selectedItems);
                                     },
-                       _setDisabled:function(value)
+                       _setDisabledAttr:function(value)
                                     {
                                       this._selectButton.set("disabled", 
value);
                                     },
-                       _getDisabled:function()
+                       _getDisabledAttr:function()
                                     {
                                       return  
this._selectButton.get("disabled")
                                     },

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryBuilder.js
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryBuilder.js?rev=1741469&r1=1741468&r2=1741469&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryBuilder.js
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryBuilder.js
 Thu Apr 28 16:22:56 2016
@@ -33,6 +33,7 @@ define(["dojo/_base/declare",
         "dgrid/extensions/ColumnResizer",
         "dstore/Memory",
         'dstore/legacy/DstoreAdapter',
+        "qpid/management/query/QueryStore",
         "qpid/management/query/DropDownSelect",
         "qpid/management/query/WhereExpression",
         "dojo/Evented",
@@ -72,27 +73,12 @@ define(["dojo/_base/declare",
                  ColumnResizer,
                  Memory,
                  DstoreAdapter,
-                 DropDownSelect,
-                 WhereExpression
+                 QueryStore
                  )
         {
-            var arrayToSelectExpression =   function(value)
-                                            {
-                                              var expression = "";
-                                              if (lang.isArray(value))
-                                              {
-                                                for(var i=0; i<value.length 
;i++)
-                                                {
-                                                  var selection = value[i] && 
value[i].hasOwnProperty("attributeName") ?
-                                                                  
value[i].attributeName : value[i];
-                                                  expression = expression + (i 
> 0 ? "," : "") + selection;
-                                                }
-                                              }
-                                              return expression;
-                                            };
             var predefinedCategories =      [ {id: "queue", name: "Queue"},  
{id: "connection", name: "Connection"} ];
 
-            return declare( "qpid.management.query.QueryBuilder",
+            var QueryBuilder = declare( "qpid.management.query.QueryBuilder",
                             [dijit._Widget, dijit._TemplatedMixin, 
dijit._WidgetsInTemplateMixin],
                             {
                                  //Strip out the apache comment header from 
the template html as comments unsupported.
@@ -104,15 +90,16 @@ define(["dojo/_base/declare",
                                 scope:null,
                                 categoryName: null,
                                 advancedSearch: null,
-                                selectExpression: null,
-                                whereExpression: null,
+                                advancedSelect: null,
+                                advancedWhere: null,
                                 standardSearch: null,
-                                selectColumnsButton: null,
-                                selectWhereButton: null,
+                                standardSelectChooser: null,
+                                standardWhereChooser: null,
                                 searchButton: null,
                                 modeButton: null,
-                                whereExpressionBuilder: null,
+                                standardWhereExpressionBuilder: null,
                                 queryResultGrid: null,
+                                advancedOrderBy: null,
 
                                 /**
                                  * constructor parameter
@@ -123,14 +110,12 @@ define(["dojo/_base/declare",
                                  * Inner fields
                                  */
                                 _standardMode: true,
-                                _standardModeLastWhereExpression: null,
-                                _standardModeLastSelectExpression: null,
                                 _scopeModelObjects: {},
                                 _categorySelector: null,
                                 _searchScopeSelector: null,
-                                _lastCategory: null,
-                                _lastSearchQuery: null,
-                                _showWarningOnChangesInAdvancedMode: true,
+                                _lastStandardModeSelect: [],
+                                _sort: [],
+                                _lastHeaders: [],
 
                                 constructor: function(args)
                                              {
@@ -152,214 +137,218 @@ define(["dojo/_base/declare",
                                                this._createCategoryList();
 
                                                // advanced mode widgets
-                                               this.whereExpression.on("blur", 
lang.hitch(this, this._showAdvanceModeWarningIfRequired));
-                                               
this.selectExpression.on("blur", lang.hitch(this, 
this._showAdvanceModeWarningIfRequired));
-                                               
this.selectExpression.on("change", lang.hitch(this, 
this._advancedModeSelectChanged));
-                                               
this.selectExpression.on("keyUp", lang.hitch(this, 
this._advancedModeKeyPressed));
-                                               
this.whereExpression.on("keyUp", lang.hitch(this, 
this._advancedModeKeyPressed));
+                                               
this.advancedSelect.on("change", lang.hitch(this, this._toggleSearchButton));
+                                               this.advancedSelect.on("blur", 
lang.hitch(this, this._advancedModeSelectChanged));
+                                               this.advancedWhere.on("blur", 
lang.hitch(this, this._advancedModeWhereChanged));
+                                               this.advancedOrderBy.on("blur", 
lang.hitch(this, this._advancedModeOrderByChanged));
+                                               
this.advancedSelect.on("keyDown", lang.hitch(this, 
this._advancedModeKeyPressed));
+                                               
this.advancedWhere.on("keyDown", lang.hitch(this, 
this._advancedModeKeyPressed));
+                                               
this.advancedOrderBy.on("keyDown", lang.hitch(this, 
this._advancedModeKeyPressed));
 
                                                // standard mode widgets
-                                               
this.selectColumnsButton.on("change", lang.hitch(this, 
this._standardModeSelectChanged));
-                                               
this.selectColumnsButton.startup();
-                                               
this.selectWhereButton.startup();
-                                               
this.whereExpressionBuilder.set("whereFieldsSelector", this.selectWhereButton );
-                                               
this.whereExpressionBuilder.set("userPreferences", 
this._management.userPreferences );
-                                               
this.whereExpressionBuilder.startup();
-                                               
this.whereExpressionBuilder.on("change", lang.hitch(this, 
this._standardModeWhereChanged));
+                                               
this.standardSelectChooser.on("change", lang.hitch(this, 
this._standardModeSelectChanged));
+                                               
this.standardSelectChooser.startup();
+                                               
this.standardWhereChooser.startup();
+                                               
this.standardWhereExpressionBuilder.set("whereFieldsSelector", 
this.standardWhereChooser );
+                                               
this.standardWhereExpressionBuilder.set("userPreferences", 
this._management.userPreferences );
+                                               
this.standardWhereExpressionBuilder.startup();
+                                               
this.standardWhereExpressionBuilder.on("change", lang.hitch(this, 
this._standardModeWhereChanged));
 
                                                // search & mode buttons
                                                this.searchButton.on("click", 
lang.hitch(this, this.search));
-                                               this.modeButton.on("click", 
lang.hitch(this, this._modeChanged));
+                                               this.modeButton.on("click", 
lang.hitch(this, this._showModeSwitchWarningIfRequired));
 
+                                               this._buildGrid();
                                                this._categoryChanged();
                                                this._toggleSearchButton();
                                              },
                                 search:      function()
                                              {
-                                               var select, where, callback;
-                                               if (this._standardMode)
-                                               {
-                                                  select = 
this._standardModeLastSelectExpression;
-                                                  where = 
this._standardModeLastWhereExpression;
-                                               }
-                                               else
-                                               {
-                                                 select = 
this.selectExpression.value;
-                                                 where = 
this.whereExpression.value;
-                                                 callback = lang.hitch(this, 
this._resetStandardSearchWidgetsIfAdvancedChanged);
-                                               }
-
-                                               var category = 
this._categorySelector.value.toLowerCase();
-                                               if (select && category)
-                                               {
+                                                 var category = 
this._categorySelector.value.toLowerCase();
                                                  var scope = 
this._searchScopeSelector.value;
-                                                 this._lastSearchQuery = 
{scope:scope, select: select, where: where, category: category};
                                                  var modelObj = 
this._scopeModelObjects[scope];
-                                                 this._doSearch( modelObj, 
category, select, where, callback);
-                                               }
+                                                 this._store.selectClause = 
this._store.selectClause;
+                                                 this._store.where = 
this._store.where;
+                                                 this._store.category = 
category;
+                                                 this._store.parent = modelObj;
+                                                 this._store.orderBy = 
this._store.orderBy;
+                                                 this._resultsGrid.refresh();
                                              },
-                                _doSearch:   function(modelObj, category, 
select, where, callback)
+                                _showModeSwitchWarningIfRequired: function()
+                                            {
+                                                var userPreferences = 
this._management.userPreferences;
+                                                var displayWarning = 
(!userPreferences || !userPreferences.query ||
+                                                                      
(userPreferences.query.displaySwitchModeWarning == undefined ||
+                                                                       
userPreferences.query.displaySwitchModeWarning));
+                                                if (this._standardMode && 
displayWarning && QueryBuilder.showWarningOnModeChange)
+                                                {
+                                                    if 
(!this._switchModeWarningDialog)
+                                                    {
+                                                        var formattedMessage = 
"<div>Switching to advanced mode is a one-way street,<br/>"
+                                                            + "switching back 
from advanced mode to standard mode will<br/>"
+                                                            + "completely 
reset the query.</div>";
+                                                        
this._switchModeWarningDialog = new qpid.management.query.MessageDialog({
+                                                            title: "Warning!",
+                                                            message: 
formattedMessage},
+                                                            
domConstruct.create("div"));
+                                                        
this._switchModeWarningDialog.on("execute",
+                                                            lang.hitch(this, 
function(stopDisplaying)
+                                                            {
+                                                                if 
(stopDisplaying)
+                                                                {
+                                                                    if 
(!userPreferences.query)
+                                                                    {
+                                                                        
userPreferences.query = {};
+                                                                    }
+                                                                    
userPreferences.query.displaySwitchModeWarning = false;
+                                                                    
userPreferences.save({query: userPreferences.query},
+                                                                        null,
+                                                                        
function(error){console.log("Saving user preferences failed: " + error);}
+                                                                    );
+                                                                }
+                                                                else
+                                                                {
+                                                                    
QueryBuilder.showWarningOnModeChange = false;
+                                                                }
+                                                                
this._modeChanged();
+                                                            }));
+                                                    }
+                                                    
this._switchModeWarningDialog.show();
+                                                }
+                                                else
+                                                {
+                                                    this._modeChanged();
+                                                }
+                                            },
+                                _advancedModeSelectChanged: function()
                                              {
-                                               var that = this;
-                                               var result = 
this._management.query({select: select,
-                                                                               
     where: where,
-                                                                               
     parent: modelObj,
-                                                                               
     category: category});
-                                               result.then(function(data)
-                                                           {
-                                                             
that._showResults(data.results, data.headers);
-                                                             if (callback)
-                                                             {
-                                                               callback();
-                                                             }
-                                                           },
-                                                           function(error)
-                                                           {
-                                                             if (error && 
error.response && error.response.status == 404)
-                                                             {
-                                                               
that._showResults([], []);
-                                                             }
-                                                             else
-                                                             {
-                                                               
alert(error.message ? error.message: error);
-                                                             }
-                                                           });
+                                               this._store.selectClause = 
this.advancedSelect.value;
+                                             },
+                                _advancedModeWhereChanged: function()
+                                             {
+                                                 this._store.where = 
this.advancedWhere.value;
+                                             },
+                                _advancedModeOrderByChanged: function()
+                                            {
+                                                this._store.orderBy = 
this.advancedOrderBy.value;
+                                            },
+                                _toggleSearchButton: function(select)
+                                             {
+                                               var criteriaNotSet = !select;
+                                               
this.searchButton.set("disabled",criteriaNotSet);
+                                               this.searchButton.set("title", 
criteriaNotSet?"Please, choose fields to display in order to enable 
search":"Search");
                                              },
-                                _showAdvanceModeWarningIfRequired: function()
+                                _buildOrderByExpression: function()
                                              {
-                                               if (!this._standardMode &&
-                                                    ( 
this.selectExpression.value != this._standardModeLastSelectExpression ||
-                                                      
this.whereExpression.value != this._standardModeLastWhereExpression ))
+                                               var orderByExpression = "";
+                                               if (this._sort && 
this._sort.length)
                                                {
-                                                 var userPreferences = 
this._management.userPreferences;
-                                                 var displayWarning = 
!userPreferences || !userPreferences.query ||
-                                                                     
(userPreferences.query.displaySwitchModeWarning == undefined
-                                                                      || 
userPreferences.query.displaySwitchModeWarning );
-                                                 if (displayWarning && 
this._showWarningOnChangesInAdvancedMode)
+                                                 var orders = []
+                                                 for (var i = 0; i < 
this._sort.length; ++i)
                                                  {
-                                                   if 
(!this._switchModeWarningDialog)
-                                                   {
-                                                     var that = this;
-                                                     var formattedMessage = 
"<div>On switching to Standard Mode,</div>"
-                                                                          + " 
<div>all modifications made to where clause</div>"
-                                                                          + " 
<div>and any expressions within the select clause will be lost.</div>";
-                                                     
this._switchModeWarningDialog = new qpid.management.query.MessageDialog({title: 
"Warning!",
-                                                                               
                                              message: formattedMessage},
-                                                                               
                                              domConstruct.create("div"));
-                                                     
this._switchModeWarningDialog.on( "execute",
-                                                                               
        function(stopDisplaying)
-                                                                               
        {
-                                                                               
          if (stopDisplaying)
-                                                                               
          {
-                                                                               
             if (!userPreferences.query)
-                                                                               
             {
-                                                                               
               userPreferences.query= {};
-                                                                               
             }
-                                                                               
             userPreferences.query.displaySwitchModeWarning = false;
-                                                                               
             userPreferences.save({query:  userPreferences.query});
-
-                                                                               
          }
-                                                                               
          else
-                                                                               
          {
-                                                                               
            that._showWarningOnChangesInAdvancedMode = false;
-                                                                               
          }
-                                                                               
          that.search();
-                                                                               
        });
-                                                     
this._switchModeWarningDialog.on( "cancel",
-                                                                               
        function(val)
-                                                                               
        {
-                                                                               
          that.whereExpression.set("value", 
that._standardModeLastWhereExpression);
-                                                                               
          that.selectExpression.set("value", 
that._standardModeLastSelectExpression);
-                                                                               
        });
-                                                   }
-                                                   
this._switchModeWarningDialog.show();
-                                                   return true;
+                                                   
orders.push(parseInt(this._sort[i].property) + (this._sort[i].descending? " 
desc" : ""));
                                                  }
+                                                 orderByExpression = 
orders.join(",");
                                                }
-                                               return false;
+                                               
this.advancedOrderBy.set("value", orderByExpression);
+                                               return orderByExpression;
                                              },
-                                _advancedModeSelectChanged: function()
+                                _buildSelectExpression: function(value)
                                              {
-                                               
this._toggleSearchButton(this.selectExpression.value);
+                                                var expression = "";
+                                                if (lang.isArray(value))
+                                                {
+                                                    for(var i=0; 
i<value.length ;i++)
+                                                    {
+                                                        var selection = 
value[i] && value[i].hasOwnProperty("attributeName") ?
+                                                            
value[i].attributeName : value[i];
+                                                        expression = 
expression + (i > 0 ? "," : "") + selection;
+                                                    }
+                                                }
+                                                return expression;
                                              },
-                                _toggleSearchButton: function(select)
+                                _normalizeSorting: function(selectedColumns)
                                              {
-                                               var criteriaNotSet = !select;
-                                               
this.searchButton.set("disabled",criteriaNotSet);
-                                               this.searchButton.set("title", 
criteriaNotSet?"Please, choose fields to display in order to enable 
search":"Search");
+                                                 var newSort = [];
+                                                 for (var i = 0; i < 
this._sort.length; ++i) {
+                                                     var sortColumnIndex = 
parseInt(this._sort[i].property) - 1;
+                                                     var sortDescending = 
this._sort[i].descending;
+                                                     if (sortColumnIndex < 
this._lastStandardModeSelect.length) {
+                                                         var 
oldSortedColumnName = 
this._lastStandardModeSelect[sortColumnIndex].attributeName;
+                                                         for (var j = 0; j < 
selectedColumns.length; ++j) {
+                                                             if 
(selectedColumns[j].attributeName === oldSortedColumnName) {
+                                                                 newSort.push({
+                                                                     property: 
"" + (j + 1),
+                                                                     
descending: sortDescending
+                                                                 });
+                                                                 break;
+                                                             }
+                                                         }
+                                                     }
+                                                 }
+                                                 this._sort = newSort;
                                              },
-                                _standardModeSelectChanged: function(result)
+                                _standardModeSelectChanged: 
function(selectedColumns)
                                              {
-                                               
this._standardModeLastSelectExpression = arrayToSelectExpression(result);
-                                               
this.selectExpression.set("value", this._standardModeLastSelectExpression);
+                                               
this._normalizeSorting(selectedColumns);
+                                               this._store.orderBy = 
this._buildOrderByExpression();
+                                               this._store.selectClause = 
this._buildSelectExpression(selectedColumns);
+                                               this._lastStandardModeSelect = 
lang.clone(selectedColumns);
+                                               
this._toggleSearchButton(this._store.selectClause);
                                                this.search();
                                              },
                                 _standardModeWhereChanged: function(result)
                                              {
-                                                
this._standardModeLastWhereExpression = result;
-                                                
this.whereExpression.set("value", result);
+                                                this._store.where = result;
                                                 this.search();
                                              },
-                                _resetStandardSearchWidgetsIfAdvancedChanged: 
function()
+                                _buildGrid:  function()
                                              {
-                                               if 
(this._standardModeLastWhereExpression && this._standardModeLastWhereExpression 
!= this.whereExpression.value)
-                                               {
-                                                 
this._standardModeLastWhereExpression = "";
-                                                 
this.whereExpressionBuilder.clearWhereCriteria();
-                                               }
-
-                                               if 
(this._standardModeLastSelectExpression != this.selectExpression.value)
-                                               {
-                                                 
this._standardModeLastSelectExpression = this.selectExpression.value;
+                                                this._store = new QueryStore({
+                                                    management: 
this.management,
+                                                    category: 
this._categorySelector.value.toLowerCase(),
+                                                    parent: 
this._scopeModelObjects[this._searchScopeSelector.value],
+                                                    zeroBased: false});
 
-                                                 // update selected from 
headers ignoring id
-                                                 var headers = 
lang.clone(this._lastHeaders);
-                                                 headers.shift();
-                                                 
this.selectColumnsButton.set("data", {selected: headers});
-                                                 var promise = 
this.selectColumnsButton.get("selectedItems");
-                                                 dojo.when(promise,
-                                                           lang.hitch(this,
-                                                                      
function(selectedItems)
-                                                                      {
-                                                                        var 
val = arrayToSelectExpression(selectedItems);
-                                                                        
this._standardModeLastSelectExpression = val;
-                                                                      }));
-                                               }
-                                             },
-                                _showResults:function(items, headers)
-                                             {
-                                               this._lastHeaders = headers;
-                                               var store = new Memory({data: 
items, idProperty: 0});
-                                               if (!this._resultsGrid)
-                                               {
-                                                 if (items && items.length)
-                                                 {
-                                                   this._buildGrid(store, 
this._lastHeaders);
-                                                 }
-                                               }
-                                               else
-                                               {
-                                                 
this._resultsGrid.set("collection", store);
-                                                 
this._resultsGrid.set("columns", this._getColumns(this._lastHeaders));
-                                                 this._resultsGrid.refresh();
-                                               }
-                                             },
-                                _buildGrid:  function(store, headers)
-                                             {
                                                 var CustomGrid = declare([ 
Grid, Keyboard, Selection, Pagination, ColumnResizer ]);
-                                                var grid = new CustomGrid({
-                                                                              
columns: this._getColumns(headers),
-                                                                              
collection: store,
+
+                                                var grid = new CustomGrid({   
collection: this._store,
                                                                               
rowsPerPage: 100,
                                                                               
selectionMode: 'single',
                                                                               
cellNavigation: false,
                                                                               
className: 'dgrid-autoheight',
+                                                                              
pageSizeOptions: [10,20,30,40,50,100,1000,10000,100000],
                                                                               
adjustLastColumn: true
                                                                           },
                                                                           
this.queryResultGrid);
+                                                
this._store.on("changeHeaders", lang.hitch(this, function(event) {
+                                                    
this._store.useCachedResults = true;
+                                                    grid.set("columns", 
this._getColumns(event.headers));
+                                                    this._resultsGrid.resize();
+                                                }));
                                                 this._resultsGrid = grid;
                                                 this._resultsGrid.startup();
                                                 
this._resultsGrid.on('.dgrid-row:dblclick', lang.hitch(this, this._onRowClick));
+                                                
this._resultsGrid.on("dgrid-sort", lang.hitch(this, function(event) {
+                                                    for (var i = 0; i < 
this._sort.length; ++i) {
+                                                        if 
(this._sort[i].property == event.sort[0].property) {
+                                                            
this._sort.splice(i, 1);
+                                                            break;
+                                                        }
+                                                    }
+                                                    this._sort.splice(0, 0, 
event.sort[0]);
+                                                    this._store.orderBy = 
this._buildOrderByExpression();
+                                                    event.preventDefault();
+                                                    event.stopPropagation();
+                                                    this.search();
+                                                }));
+                                                
this._resultsGrid.on("dgrid-refresh-complete",
+                                                                     
lang.hitch(this,
+                                                                               
 function()
+                                                                               
 {
+                                                                               
   this._store.useCachedResults = false;
+                                                                               
   this._resultsGrid.updateSortArrow(this._sort, true);
+                                                                               
 }));
                                              },
                                 _onRowClick: function (event)
                                              {
@@ -408,20 +397,16 @@ define(["dojo/_base/declare",
                                                               }
                                                             });
                                              },
-                                _getColumns: function(attributes)
+                                _getColumns: function(headers)
                                              {
+                                               this._lastHeaders = headers;
                                                var columns = [];
-                                               if (attributes)
+                                               if (headers)
                                                {
-                                                  for (var i in attributes)
+                                                  for (var i = 0; i < 
headers.length; ++i)
                                                   {
-                                                     if (i == 0)
-                                                     {
-                                                        // skip first id 
column as it was added by management
-                                                        continue;
-                                                     }
-                                                     var attribute = 
attributes[i];
-                                                     var column = {label: 
attribute, field: i};
+                                                     var attribute = 
headers[i];
+                                                     var column = {label: 
attribute, field: "" + (i + 1), sortable: true};
                                                      columns.push(column);
                                                      if (this._columns)
                                                      {
@@ -485,7 +470,7 @@ define(["dojo/_base/declare",
                                 _createScopeList: function()
                                              {
                                                var that = this;
-                                               var result = 
this._management.query({select: "$parent.name as parentName, name",
+                                               var result = 
this._management.query({select: "id, $parent.name as parentName, name",
                                                                                
    category : "virtualhost"});
                                                var deferred = new 
dojo.Deferred();
                                                result.then(function(data)
@@ -563,95 +548,94 @@ define(["dojo/_base/declare",
                                             },
                                 _categoryChanged: function()
                                             {
-                                              var metadata = 
this._getCategoryMetadata(this._categorySelector.value);
-                                              var disableMetadataDependant = 
!metadata;
-                                              
this.selectWhereButton.set("disabled", disableMetadataDependant);
-                                              
this.selectColumnsButton.set("disabled", disableMetadataDependant);
-                                              
this.searchButton.set("disabled", disableMetadataDependant);
-                                              if (disableMetadataDependant)
-                                              {
-                                                dijit.showTooltip(
-                                                  
this._categorySelector.get("invalidMessage"),
-                                                  
this._categorySelector.domNode,
-                                                  
this._categorySelector.get("tooltipPosition"),
-                                                  
!this._categorySelector.isLeftToRight()
-                                                );
-                                              }
-                                              else
-                                              {
-                                                if (this._lastCategory != 
this._categorySelector.value)
+                                                this._resetSearch();
+                                                var metadata = 
this._getCategoryMetadata(this._categorySelector.value);
+                                                var disableMetadataDependant = 
!metadata;
+                                                
this.standardWhereChooser.set("disabled", disableMetadataDependant);
+                                                
this.standardSelectChooser.set("disabled", disableMetadataDependant);
+                                                
this.searchButton.set("disabled", disableMetadataDependant || 
!this._store.selectClause);
+                                                
this.modeButton.set("disabled", disableMetadataDependant);
+                                                
this.advancedSelect.set("disabled", disableMetadataDependant);
+                                                
this.advancedWhere.set("disabled", disableMetadataDependant);
+                                                
this.advancedOrderBy.set("disabled", disableMetadataDependant);
+
+                                                if (disableMetadataDependant)
                                                 {
-                                                  
this._standardModeLastWhereExpression = "";
-                                                  this._lastCategory = 
this._categorySelector.value;
-                                                  
this.selectExpression.set("value", "");
-                                                  
this.whereExpression.set("value", "");
-                                                  
this.whereExpressionBuilder.clearWhereCriteria();
-                                                  var data = 
this._combineTypeAttributesAndStatistics(metadata);
-                                                  this._columns = 
data.asObject;
-                                                  
this.selectColumnsButton.set("data", {items: data.asArray,
-                                                                               
        idProperty: "id",
-                                                                               
        selected:[],
-                                                                               
        nameProperty: "attributeName"});
-                                                  
this.selectWhereButton.set("data", {items: data.asArray,
-                                                                               
       selected:[],
-                                                                               
       idProperty: "id",
-                                                                               
       nameProperty: "attributeName"});
-                                                  this._showResults([], []);
+                                                    dijit.showTooltip(
+                                                        
this._categorySelector.get("invalidMessage"),
+                                                        
this._categorySelector.domNode,
+                                                        
this._categorySelector.get("tooltipPosition"),
+                                                        
!this._categorySelector.isLeftToRight()
+                                                    );
+                                                }
+                                                else
+                                                {
+                                                    var data = 
this._combineTypeAttributesAndStatistics(metadata);
+                                                    this._columns = 
data.asObject;
+                                                    
this.standardSelectChooser.set("data", {items: data.asArray,
+                                                        idProperty: "id",
+                                                        selected:[],
+                                                        nameProperty: 
"attributeName"});
+                                                    
this.standardWhereChooser.set("data", {items: data.asArray,
+                                                        selected:[],
+                                                        idProperty: "id",
+                                                        nameProperty: 
"attributeName"});
                                                 }
-                                              }
                                             },
                                 _advancedModeKeyPressed:function(evt)
                                             {
                                               var key = evt.keyCode;
-                                              if (key == dojo.keys.ENTER && 
this.selectExpression.value)
+                                              if (key == dojo.keys.ENTER)
                                               {
-                                                if 
(!this._showAdvanceModeWarningIfRequired())
-                                                {
+                                                  evt.preventDefault();
+                                                  evt.stopPropagation();
+                                                  this._store.selectClause = 
this.advancedSelect.value;
+                                                  this._store.where = 
this.advancedWhere.value;
+                                                  this._store.orderBy = 
this.advancedOrderBy.value;
                                                   this.search();
-                                                }
                                               }
                                             },
                                 _modeChanged: function()
                                             {
-                                              this._standardMode = 
!this._standardMode
+                                              this._standardMode = 
!this._standardMode;
                                               if (!this._standardMode)
                                               {
                                                 this.modeButton.set("label", 
"Standard");
                                                 this.modeButton.set("title", 
"Switch to 'Standard' search");
-                                                
this.selectExpression.set("disabled", false);
-                                                
this.whereExpression.set("disabled", false);
+                                                
this.advancedSelect.set("disabled", false);
+                                                
this.advancedWhere.set("disabled", false);
                                                 
this.standardSearch.style.display = "none";
-                                                
this.whereExpressionBuilder.domNode.style.display = "none";
+                                                
this.standardWhereExpressionBuilder.domNode.style.display = "none";
                                                 
this.advancedSearch.style.display = "";
-                                                if (this._lastSearchQuery &&
-                                                     
(this._lastSearchQuery.select != this.selectExpression.value ||
-                                                      
this._lastSearchQuery.where != this.whereExpression.value ||
-                                                      
this._lastSearchQuery.category != this._categorySelector.value ||
-                                                      
this._lastSearchQuery.scope != this._searchScopeSelector.value))
-                                                {
-                                                  this.search();
-                                                }
+                                                
this.advancedSelect.set("value", this._store.selectClause);
+                                                
this.advancedWhere.set("value", this._store.where);
+                                                
this.advancedOrderBy.set("value", this._store.orderBy);
                                               }
                                               else
                                               {
                                                 this.modeButton.set("label", 
"Advanced");
                                                 this.modeButton.set("title", 
"Switch to 'Advanced' search using SQL-like expressions");
-                                                
this.selectExpression.set("disabled", true);
-                                                
this.whereExpression.set("disabled", true);
+                                                
this.advancedSelect.set("disabled", true);
+                                                
this.advancedWhere.set("disabled", true);
                                                 
this.standardSearch.style.display = "";
-                                                
this.whereExpressionBuilder.domNode.style.display = "";
+                                                
this.standardWhereExpressionBuilder.domNode.style.display = "";
                                                 
this.advancedSearch.style.display = "none";
-
-                                                if (this._lastSearchQuery &&
-                                                     
(this._lastSearchQuery.select != this._standardModeLastSelectExpression ||
-                                                      
this._lastSearchQuery.where != this._standardModeLastWhereExpression ||
-                                                      
this._lastSearchQuery.category != this._categorySelector.value ||
-                                                      
this._lastSearchQuery.scope != this._searchScopeSelector.value))
-                                                {
-                                                  this.search();
-                                                }
+                                                this._resetSearch();
                                               }
                                             },
+                                _resetSearch: function()
+                                            {
+                                                this._store.where = "";
+                                                this._store.selectClause = "";
+                                                this._store.orderBy = "";
+                                                
this.standardSelectChooser.set("data", {selected: []});
+                                                
this.standardWhereExpressionBuilder.clearWhereCriteria();
+                                                this._sort = [];
+                                                
this.advancedSelect.set("value", this._store.selectClause);
+                                                
this.advancedWhere.set("value", this._store.where);
+                                                
this.advancedOrderBy.set("value", this._store.orderBy);
+                                                this.search();
+                                            },
                                 _getCategoryMetadata: function(value)
                                             {
                                               if (value)
@@ -718,4 +702,8 @@ define(["dojo/_base/declare",
                                               return {asArray: columnsArray, 
asObject: columnsObject};
                                             }
                             });
+
+            QueryBuilder.showWarningOnModeChange = true;
+
+            return QueryBuilder;
         });

Added: 
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=1741469&view=auto
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryStore.js
 (added)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryStore.js
 Thu Apr 28 16:22:56 2016
@@ -0,0 +1,162 @@
+/*
+ *
+ * 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/lang',
+       'dojo/_base/declare',
+    "dojo/Evented",
+    "dojo/json",
+    'dstore/Store',
+    'dstore/QueryResults',
+    "dojo/Deferred"
+], function (lang, declare, Evented, json, Store, QueryResults,Deferred) {
+
+    return declare("qpid.management.query.QueryStore", [Store, Evented], {
+
+        management: null,
+        selectClause: null,
+        where: null,
+        category: null,
+        parent: null,
+        useCachedResults: false,
+        zeroBased: true,
+        _lastHeaders: [],
+        _lastResponsePromise: null,
+
+        fetch: function (kwArgs) {
+            return this._request(kwArgs);
+        },
+
+        fetchRange: function (kwArgs) {
+            return this._request(kwArgs);
+        },
+
+        _request: function (kwArgs) {
+
+
+            if (!this.selectClause) {
+                this._emitChangeHeadersIfNecessary([]);
+                var deferred = new Deferred();
+                deferred.resolve([]);
+                return new QueryResults(deferred.promise);
+            }
+
+            var queryRequest = {
+                category: this.category,
+                select: this.selectClause ? this.selectClause + ",id" : "id"
+            };
+
+            if (this.parent) {
+                queryRequest.parent = this.parent;
+            }
+
+            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;
+            }
+
+            if (this.useCachedResults) {
+                return this._createQueryResults(this._lastResponsePromise);
+            }
+
+            var responsePromise = this.management.query(queryRequest);
+            responsePromise.then(lang.hitch(this, function(data) {
+                var headers = lang.clone(data.headers);
+                headers.pop();
+                this._emitChangeHeadersIfNecessary(headers);
+            }), lang.hitch(this, function(error) {
+                this._emitChangeHeadersIfNecessary([]);
+            }));
+
+            this._lastResponsePromise = responsePromise;
+            return this._createQueryResults(this._lastResponsePromise);
+        },
+
+        _createQueryResults: function(responsePromise) {
+            var that = this;
+            var queryResultData = {
+                data: responsePromise.then(function (data) {
+                    var dataResults = data.results;
+                    var results = [];
+                    for (var i = 0, l = dataResults.length; i < l; ++i) {
+                        var result = dataResults[i];
+                        var item = {id: result[result.length - 1]};
+
+                        // excluding id, as we already added id field
+                        for(var j = 0, rl = result.length - 1; j < rl ; ++j ){
+                            // sql uses 1-based index in ORDER BY
+                            var field = this.zeroBased ? j : j + 1;
+                            item[new String(field)] = result[j];
+                        }
+                        results.push(item);
+                    }
+                    return results;
+                }, function(error) {
+                    this.management.errorHandler(error);
+                    return [];
+                }),
+                total: responsePromise.then(function (data) {
+                    return data.total;
+                }, function(error) {
+                    return 0;
+                })
+            };
+            return new QueryResults(queryResultData.data, {
+                totalLength: queryResultData.total
+            });
+        },
+
+        _emitChangeHeadersIfNecessary: function (headers) {
+            if (!this._equalStringArrays(headers, this._lastHeaders)) {
+                this._lastHeaders = headers;
+                this.emit("changeHeaders", {headers: headers});
+            }
+        },
+
+        // override from dstore.Store to not copy collection
+        _createSubCollection: function() {
+            return this;
+        },
+
+        _equalStringArrays: function(a, b) {
+            if (a.length != b.length) {
+                return false;
+            }
+            for (var i = 0; i < a.length; ++i) {
+                if (a[i] != b[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    });
+});

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryBuilder.html
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryBuilder.html?rev=1741469&r1=1741468&r2=1741469&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryBuilder.html
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryBuilder.html
 Thu Apr 28 16:22:56 2016
@@ -23,12 +23,12 @@
         <label>Category : <span 
data-dojo-attach-point="categoryName"></span></label>
         <span data-dojo-attach-point="standardSearch">
             <span data-dojo-type="qpid/management/query/DropDownSelect"
-                 data-dojo-attach-point="selectColumnsButton"
+                 data-dojo-attach-point="standardSelectChooser"
                  data-dojo-props="title: 'Select fields to 
display',label:'Columns'">
             </span>
 
             <span data-dojo-type="qpid/management/query/DropDownSelect"
-                  data-dojo-attach-point="selectWhereButton"
+                  data-dojo-attach-point="standardWhereChooser"
                   data-dojo-props="title: 'Specify Filtering 
Conditions',label:'Conditions'">
             </span>
         </span>
@@ -40,13 +40,13 @@
              data-dojo-props="title:'Switch to \'Advanced\' search using 
SQL-like expressions'"
              class="alignRight">Advanced</div>
         <div class="clear"></div>
-        <div data-dojo-attach-point="whereExpressionBuilder"
+        <div data-dojo-attach-point="standardWhereExpressionBuilder"
              data-dojo-type="qpid/management/query/WhereExpression" 
class="dijitToolbar"></div>
         <div data-dojo-attach-point="advancedSearch"  style="display:none;">
             <div class="advancedSearchItem">
                 <div class="advancedSearchLabel">Select :</div>
                 <div class="advancedSearchField">
-                    <textarea data-dojo-attach-point="selectExpression" 
type="text"
+                    <textarea data-dojo-attach-point="advancedSelect" 
type="text"
                                data-dojo-type="dijit/form/SimpleTextarea"
                                data-dojo-props=" name: 'select',
                                                  rows: 1,
@@ -59,13 +59,26 @@
             <div class="advancedSearchItem">
                 <div class="advancedSearchLabel">Where : </div>
                 <div class="advancedSearchField" >
-                    <textarea data-dojo-attach-point="whereExpression" 
type="text"
+                    <textarea data-dojo-attach-point="advancedWhere" 
type="text"
                               data-dojo-type="dijit/form/SimpleTextarea"
                               data-dojo-props=" name: 'where',
                                                 rows: 1,
                                                 intermediateChanges: true,
                                                 placeHolder: 'where 
expression',
-                                                title: 'Enter sql like where 
conditions',
+                                                title: 'Enter where conditions 
using sql syntax',
+                                                promptMessage: 'Use JMS filter 
syntax to specify where conditions'" rows="1"></textarea>
+                </div>
+            </div>
+            <div class="advancedSearchItem">
+                <div class="advancedSearchLabel">Order : </div>
+                <div class="advancedSearchField" >
+                    <textarea data-dojo-attach-point="advancedOrderBy" 
type="text"
+                              data-dojo-type="dijit/form/SimpleTextarea"
+                              data-dojo-props=" name: 'orderBy',
+                                                rows: 1,
+                                                intermediateChanges: true,
+                                                placeHolder: 'order 
expression',
+                                                title: 'Enter order by 
conditions using sql syntax',
                                                 promptMessage: 'Use JMS filter 
syntax to specify where conditions'" rows="1"></textarea>
                 </div>
             </div>

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/query/ConfiguredObjectQueryTest.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/query/ConfiguredObjectQueryTest.java?rev=1741469&r1=1741468&r2=1741469&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/query/ConfiguredObjectQueryTest.java
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/query/ConfiguredObjectQueryTest.java
 Thu Apr 28 16:22:56 2016
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.when;
 
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -96,6 +97,7 @@ public class ConfiguredObjectQueryTest e
         {{
             put(ConfiguredObject.ID, object1Uuid);
             put(ConfiguredObject.NAME, object1Name);
+            put("foo", "bar");
         }});
 
         ConfiguredObject obj2 = createCO(new HashMap<String, Object>()
@@ -147,6 +149,21 @@ public class ConfiguredObjectQueryTest e
         assertEquals("Unexpected row", Lists.newArrayList(objectUuid, 1234), 
row);
     }
 
+    public void testSelectClause_NonExistingColumn() throws Exception
+    {
+       ConfiguredObject obj = createCO(new HashMap<String, Object>()
+        {{
+            put(ConfiguredObject.ID, UUID.randomUUID());
+        }});
+        _objects.add(obj);
+
+        _query = new ConfiguredObjectQuery(_objects, String.format("foo"), 
null);
+        List<List<Object>> results = _query.getResults();
+        assertEquals("Unexpected number of results", 1, results.size());
+        assertEquals("Unexpected headers", Collections.singletonList("foo"), 
_query.getHeaders());
+        assertEquals("Unexpected row", Collections.singletonList(null), 
results.get(0));
+    }
+
     public void testSelectClause_ColumnAliases() throws Exception
     {
         final UUID objectUuid = UUID.randomUUID();
@@ -459,6 +476,185 @@ public class ConfiguredObjectQueryTest e
         }
     }
 
+    public void testSingleOrderByClause() throws Exception
+    {
+        final int NUMBER_OF_OBJECTS = 3;
+
+        for (int i = 0; i < NUMBER_OF_OBJECTS; ++i)
+        {
+            final int foo = (i + 1) % NUMBER_OF_OBJECTS;
+            ConfiguredObject object = createCO(new HashMap<String, Object>()
+            {{
+                put("foo", foo);
+            }});
+            _objects.add(object);
+        }
+
+        ConfiguredObject object = createCO(new HashMap<String, Object>()
+        {{
+            put("foo", null);
+        }});
+        _objects.add(object);
+
+        List<List<Object>> results;
+
+        _query = new ConfiguredObjectQuery(_objects, "foo", null, "foo ASC");
+        results = _query.getResults();
+        assertQueryResults(new Object[][]{{null}, {0}, {1}, {2}}, results);
+
+        _query = new ConfiguredObjectQuery(_objects, "foo", null, "foo DESC");
+        results = _query.getResults();
+        assertQueryResults(new Object[][]{{2}, {1}, {0}, {null}}, results);
+
+        // if not specified order should be ASC
+        _query = new ConfiguredObjectQuery(_objects, "foo", null, "foo");
+        results = _query.getResults();
+        assertQueryResults(new Object[][]{{null}, {0}, {1}, {2}}, results);
+    }
+
+    public void testTwoOrderByClauses() throws Exception
+    {
+        ConfiguredObject object;
+
+        object = createCO(new HashMap<String, Object>()
+        {{
+            put("foo", 1);
+            put("bar", 1);
+        }});
+        _objects.add(object);
+
+        object = createCO(new HashMap<String, Object>()
+        {{
+            put("foo", 1);
+            put("bar", 2);
+        }});
+        _objects.add(object);
+
+        object = createCO(new HashMap<String, Object>()
+        {{
+            put("foo", 2);
+            put("bar", 0);
+        }});
+        _objects.add(object);
+
+        _query = new ConfiguredObjectQuery(_objects, "foo,bar", null, "foo, 
bar");
+        assertQueryResults(new Object[][]{{1, 1}, {1, 2}, {2, 0}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo,bar", null, "foo 
DESC, bar");
+        assertQueryResults(new Object[][]{{2, 0}, {1, 1}, {1, 2}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo,bar", null, "foo 
DESC, bar DESC");
+        assertQueryResults(new Object[][]{{2, 0}, {1, 2}, {1, 1}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo,bar", null, "foo, 
bar DESC");
+        assertQueryResults(new Object[][]{{1, 2}, {1, 1}, {2, 0}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo,bar", null, "bar, 
foo");
+        assertQueryResults(new Object[][]{{2, 0}, {1, 1}, {1, 2}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo,bar", null, "bar 
DESC, foo");
+        assertQueryResults(new Object[][]{{1, 2}, {1, 1}, {2, 0}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo,bar", null, "bar, 
foo DESC");
+        assertQueryResults(new Object[][]{{2, 0}, {1, 1}, {1, 2}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo,bar", null, "bar 
DESC, foo DESC");
+        assertQueryResults(new Object[][]{{1, 2}, {1, 1}, {2, 0}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo,bar", null, "boo 
DESC, foo DESC, bar");
+        assertQueryResults(new Object[][]{{2, 0}, {1, 1}, {1, 2}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo, bar", null, "1, 2");
+        assertQueryResults(new Object[][]{{1, 1}, {1, 2}, {2, 0}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo, bar", null, "2, 1");
+        assertQueryResults(new Object[][]{{2, 0}, {1, 1}, {1, 2}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "foo, bar", null, "foo, 2 
DESC");
+        assertQueryResults(new Object[][]{{1, 2}, {1, 1}, {2, 0}}, 
_query.getResults());
+    }
+
+    public void testOrderByWithInvalidColumnIndex()
+    {
+        try
+        {
+            new ConfiguredObjectQuery(_objects, "id", null, "2");
+            fail("Exception is expected for column index out of bounds");
+        }
+        catch (EvaluationException e)
+        {
+            // pass
+        }
+
+        try
+        {
+            new ConfiguredObjectQuery(_objects, "id", null, "0 DESC");
+            fail("Exception is expected for column index 0");
+        }
+        catch (EvaluationException e)
+        {
+            // pass
+        }
+    }
+
+
+    public void testLimitWithoutOffset() throws Exception
+    {
+        int numberOfTestObjects = 3;
+        for(int i=0;i<numberOfTestObjects;i++)
+        {
+            final String name = "test-" + i;
+            ConfiguredObject object = createCO(new HashMap<String, Object>()
+            {{
+                put("name", name);
+            }});
+            _objects.add(object);
+        }
+
+        _query = new ConfiguredObjectQuery(_objects, "name", null, "name", 
"1", "0");
+        assertQueryResults(new Object[][]{{"test-0"}}, _query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "name", null, "name", 
"1", "1");
+        assertQueryResults(new Object[][]{{"test-1"}}, _query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "name", null, "name", 
"1", "3");
+        assertQueryResults(new Object[0][1], _query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "name", null, "name", 
"-1", "1");
+        assertQueryResults(new Object[][]{{"test-1"},{"test-2"}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "name", null, "name", 
"-1", "-4");
+        assertQueryResults(new Object[][]{{"test-0"},{"test-1"},{"test-2"}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "name", null, "name", 
"-1", "-2");
+        assertQueryResults(new Object[][]{{"test-1"},{"test-2"}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "name", null, "name", 
"invalidLimit", "invalidOffset");
+        assertQueryResults(new Object[][]{{"test-0"},{"test-1"},{"test-2"}}, 
_query.getResults());
+
+        _query = new ConfiguredObjectQuery(_objects, "name", null, "name", 
null, null);
+        assertQueryResults(new Object[][]{{"test-0"},{"test-1"},{"test-2"}}, 
_query.getResults());
+    }
+
+    private void assertQueryResults(final Object[][] expectedAttributes,
+                                    final List<List<Object>> results)
+    {
+        final int rows = expectedAttributes.length;
+        assertEquals("Unexpected number of result rows", rows, results.size());
+        if (rows > 0)
+        {
+            final int cols = expectedAttributes[0].length;
+            for (int row = 0; row < rows; ++row)
+            {
+                assertEquals("Unexpected number of result columns", cols, 
results.get(row).size());
+                for (int col = 0; col < cols; ++col)
+                {
+                    assertEquals("Unexpected row order", 
expectedAttributes[row][col], results.get(row).get(col));
+                }
+            }
+        }
+    }
+
     private ConfiguredObject createCO(final HashMap<String, Object> map)
     {
         ConfiguredObject object = mock(ConfiguredObject.class);




---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to