modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java | 174 +++++-----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/EnhancedSearchBar.java | 1
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/FavoritesSearchStrategy.java | 85 ++--
3 files changed, 153 insertions(+), 107 deletions(-)
New commits:
commit cdd21b21fc4fa8bb548c24a1147dd36704ebf0ac
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Apr 8 14:03:17 2013 -0400
Bug 921927
Prevent concurrent searches for suggestion list entries or saved searches.
Timing issues could cause duplicates to show up in the list.
Also:
- fix an issue with return key handling, which should not fire off
another suggest list update but only hide the suggest list and perform the
resource list query.
- stop ignoring the Backspace character when editing the search textbox
entry. I found it unintuitive that only adding characters could trigger
a search.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java
index d2089b4..1edd076 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java
@@ -45,6 +45,9 @@ import org.rhq.enterprise.gui.coregui.client.util.Log;
*/
public class BasicSearchStrategy extends AbstractSearchStrategy {
+ private boolean isSearchInProgress = false;
+ private String pendingSearchExpression = null;
+
public BasicSearchStrategy(EnhancedSearchBar searchBar) {
super(searchBar);
}
@@ -71,6 +74,11 @@ public class BasicSearchStrategy extends AbstractSearchStrategy {
return sb.toString();
}
+ @Override
+ public int getCellHeight() {
+ return 20;
+ }
+
/**
* Executed when this field is clicked on. Note that if {@link
* com.smartgwt.client.widgets.grid.ListGrid#addRecordClickHandler ListGrid.recordClick} is also defined, it will be fired
@@ -84,21 +92,21 @@ public class BasicSearchStrategy extends AbstractSearchStrategy {
Log.debug("BasicSearchStrategy click");
String kind = event.getRecord().getAttribute(ATTR_KIND);
- String pattern;
+ String searchExpression;
if (kind.equals("SAVED") || kind.equals("GLOBAL")) {
Log.debug("Saved or Global Search Click");
- pattern = event.getRecord().getAttribute(ATTR_PATTERN);
+ searchExpression = event.getRecord().getAttribute(ATTR_PATTERN);
} else {
Log.debug("Regular Search Click");
- pattern = event.getRecord().getAttribute(ATTR_NAME);
+ searchExpression = event.getRecord().getAttribute(ATTR_NAME);
}
searchBar.getSearchTextItem().focusInItem();
- if (!(null == pattern || pattern.isEmpty())) {
- searchBar.getSearchTextItem().setValue(pattern);
- getTabAwareSearchSuggestions(SearchSubsystem.RESOURCE, pattern, pattern.length());
+ if (!(null == searchExpression || searchExpression.isEmpty())) {
+ searchBar.getSearchTextItem().setValue(searchExpression);
+ doSearch(searchExpression);
}
}
@@ -118,109 +126,135 @@ public class BasicSearchStrategy extends AbstractSearchStrategy {
@Override
public void searchReturnKeyHandler(KeyUpEvent keyUpEvent) {
- doSearch((String) keyUpEvent.getItem().getValue());
+ searchBar.getPickListGrid().hide();
}
private void doSearch(String searchExpression) {
+ if (isSearchInProgress) {
+ Log.debug("Adding pending search [" + searchExpression + "]");
+ pendingSearchExpression = (null == searchExpression) ? "" : searchExpression;
+ return;
+ }
+
+ Log.debug("Search Start");
+ isSearchInProgress = true;
+
if (null == searchExpression || searchExpression.isEmpty()) {
Log.debug("Empty Search expression");
- getTabAwareSearchSuggestions(SearchSubsystem.RESOURCE, null, 0);
+ getSearchSuggestions(SearchSubsystem.RESOURCE, null, 0);
+
} else {
Log.debug("doSearch: " + searchExpression);
- getTabAwareSearchSuggestions(SearchSubsystem.RESOURCE, searchBar.getSearchTextItem().getValueAsString(),
- searchBar.getSearchTextItem().getValueAsString().length());
+ getSearchSuggestions(SearchSubsystem.RESOURCE, searchBar.getSearchTextItem().getValueAsString(), searchBar
+ .getSearchTextItem().getValueAsString().length());
}
-
- // don't obscure the results
- searchBar.getPickListGrid().hide();
}
- @Override
- public int getCellHeight() {
- return 20;
- }
-
- private void getTabAwareSearchSuggestions(final SearchSubsystem searchSubsystem, final String expression,
- int caretPosition) {
+ private void getSearchSuggestions(final SearchSubsystem searchSubsystem, final String expression, int caretPosition) {
final long suggestStart = System.currentTimeMillis();
Log.debug("Searching for: " + expression);
+
searchService.getTabAwareSuggestions(searchSubsystem, expression, caretPosition, null,
new AsyncCallback<List<SearchSuggestion>>() {
@Override
public void onSuccess(List<SearchSuggestion> results) {
- ListGrid searchBarPickListGrid = searchBar.getPickListGrid();
- DataSource ds = searchBarPickListGrid.getDataSource();
- // create the datasource if needed
- if (null == ds) {
- ds = new DataSource();
- ds.setClientOnly(true);
- DataSourceTextField idField = new DataSourceTextField(ATTR_ID, "Id");
- idField.setPrimaryKey(true);
- idField.setCanView(false);
+ try {
+ ListGrid searchBarPickListGrid = searchBar.getPickListGrid();
+ DataSource ds = searchBarPickListGrid.getDataSource();
+
+ // create the datasource if needed
+ if (null == ds) {
+ ds = new DataSource();
+ ds.setClientOnly(true);
+ DataSourceTextField idField = new DataSourceTextField(ATTR_ID, "Id");
+ idField.setPrimaryKey(true);
+ idField.setCanView(false);
- DataSourceTextField valueField = new DataSourceTextField(ATTR_VALUE, "Value");
+ DataSourceTextField valueField = new DataSourceTextField(ATTR_VALUE, "Value");
- ds.setFields(idField, valueField);
+ ds.setFields(idField, valueField);
- searchBarPickListGrid.setDataSource(ds);
- ListGridField[] fields = searchBarPickListGrid.getAllFields();
- searchBarPickListGrid.getField(ATTR_VALUE).setShowHover(true);
- searchBarPickListGrid.getField(ATTR_VALUE).setHoverCustomizer(new HoverCustomizer() {
+ searchBarPickListGrid.setDataSource(ds);
+ ListGridField[] fields = searchBarPickListGrid.getAllFields();
+ searchBarPickListGrid.getField(ATTR_VALUE).setShowHover(true);
+ searchBarPickListGrid.getField(ATTR_VALUE).setHoverCustomizer(new HoverCustomizer() {
- public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
- String kind = record.getAttribute(ATTR_KIND);
- if (kind.equals("SAVED") || kind.equals("GLOBAL")) {
- String pattern = record.getAttribute(ATTR_PATTERN);
+ public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
+ if (null == record) {
+ return "";
+ }
+ String kind = record.getAttribute(ATTR_KIND);
+ if (kind.equals("SAVED") || kind.equals("GLOBAL")) {
+ String pattern = record.getAttribute(ATTR_PATTERN);
- if (!(null == pattern || pattern.isEmpty())) {
- return pattern;
+ if (!(null == pattern || pattern.isEmpty())) {
+ return pattern;
+ }
}
+
+ return "";
}
+ });
- return null;
- }
- });
+ } else {
+ ds.invalidateCache();
+ }
- } else {
- ds.invalidateCache();
- }
+ for (SearchSuggestion searchSuggestion : results) {
+ Log.debug("search tab aware Suggestions: " + searchSuggestion.getKind() + ", "
+ + searchSuggestion.getValue() + ", " + searchSuggestion.getLabel());
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute(ATTR_ID, searchSuggestion.getValue());
+ if (null != searchSuggestion.getKind()) {
+ record.setAttribute(ATTR_KIND, searchSuggestion.getKind().getDisplayName());
+ }
+ record.setAttribute(ATTR_NAME, searchSuggestion.getLabel());
+ record.setAttribute(ATTR_VALUE, searchSuggestion.getValue());
+ String pattern = searchSuggestion.getOptional();
+ record.setAttribute(ATTR_PATTERN, (null == pattern) ? "" : pattern);
+ ds.addData(record);
+ }
- for (SearchSuggestion searchSuggestion : results) {
- Log.debug("search tab aware Suggestions: " + searchSuggestion.getKind() + ", "
- + searchSuggestion.getValue() + ", " + searchSuggestion.getLabel());
- ListGridRecord record = new ListGridRecord();
- record.setAttribute(ATTR_ID, searchSuggestion.getValue());
- if (null != searchSuggestion.getKind()) {
- record.setAttribute(ATTR_KIND, searchSuggestion.getKind().getDisplayName());
+ try {
+ searchBarPickListGrid.setData(new ListGridRecord[] {});
+ searchBarPickListGrid.fetchData();
+ } catch (Exception e) {
+ Log.debug("Caught exception on fetchData: " + e);
}
- record.setAttribute(ATTR_NAME, searchSuggestion.getLabel());
- record.setAttribute(ATTR_VALUE, searchSuggestion.getValue());
- String pattern = searchSuggestion.getOptional();
- record.setAttribute(ATTR_PATTERN, (null == pattern) ? "" : pattern);
- ds.addData(record);
- }
- try {
- searchBarPickListGrid.setData(new ListGridRecord[] {});
- searchBarPickListGrid.fetchData();
- } catch (Exception e) {
- Log.debug("Caught exception on fetchData: " + e);
- }
+ long suggestFetchTime = System.currentTimeMillis() - suggestStart;
+ Log.debug(results.size() + " suggestions searches fetched in: " + suggestFetchTime + "ms");
+
+ } finally {
+ // By the time we're done it's possible the results are already obsolete. If so, kick
+ // off another search.
+ Log.debug("Search End");
+
+ if (null == pendingSearchExpression) {
+ isSearchInProgress = false;
+
+ } else {
+ Log.debug("Performing pending search [" + pendingSearchExpression + "]");
- long suggestFetchTime = System.currentTimeMillis() - suggestStart;
- Log.debug(results.size() + " suggestions searches fetched in: " + suggestFetchTime + "ms");
+ String searchExpression = pendingSearchExpression;
+ pendingSearchExpression = null;
+ isSearchInProgress = false;
+ doSearch(searchExpression);
+ }
+ }
}
@Override
public void onFailure(Throwable caught) {
+ Log.debug("Search End");
+ isSearchInProgress = false;
+ pendingSearchExpression = null;
CoreGUI.getErrorHandler().handleError(MSG.view_searchBar_suggest_failSuggest(), caught);
}
-
});
}
-
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/EnhancedSearchBar.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/EnhancedSearchBar.java
index dcc7bda..add7a01 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/EnhancedSearchBar.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/EnhancedSearchBar.java
@@ -88,7 +88,6 @@ public class EnhancedSearchBar extends ToolStrip {
IGNORED_KEYS.add("Arrow_Up");
IGNORED_KEYS.add("Arrow_Left");
IGNORED_KEYS.add("Arrow_Right");
- IGNORED_KEYS.add("Backspace");
}
enum SearchMode {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/FavoritesSearchStrategy.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/FavoritesSearchStrategy.java
index fdd8fa5..44f20e2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/FavoritesSearchStrategy.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/FavoritesSearchStrategy.java
@@ -50,6 +50,8 @@ import org.rhq.enterprise.gui.coregui.client.util.message.Message;
*/
public class FavoritesSearchStrategy extends AbstractSearchStrategy {
+ private boolean isSearchInProgress = false;
+
public FavoritesSearchStrategy(EnhancedSearchBar searchBar) {
super(searchBar);
}
@@ -97,7 +99,6 @@ public class FavoritesSearchStrategy extends AbstractSearchStrategy {
if (confirmed) {
Integer id = record.getAttributeAsInt(ATTR_ID);
-
GWTServiceLookup.getSearchService().deleteSavedSearch(id, new AsyncCallback<Void>() {
@Override
@@ -132,6 +133,11 @@ public class FavoritesSearchStrategy extends AbstractSearchStrategy {
private void populateSavedSearches() {
+ // avoid concurrent searches
+ if (isSearchInProgress) {
+ return;
+ }
+
Log.debug("Search Saved Searches");
SavedSearchCriteria savedSearchCriteria = new SavedSearchCriteria();
Subject subject = UserSessionManager.getSessionSubject();
@@ -140,51 +146,58 @@ public class FavoritesSearchStrategy extends AbstractSearchStrategy {
final long startTime = System.currentTimeMillis();
searchBar.getPickListGrid().setData(new ListGridRecord[] {});
+ isSearchInProgress = true;
+
searchService.findSavedSearchesByCriteria(savedSearchCriteria, new AsyncCallback<List<SavedSearch>>() {
@Override
public void onFailure(Throwable caught) {
+ isSearchInProgress = false;
CoreGUI.getErrorHandler().handleError(MSG.view_searchBar_savedSearch_failFetch(), caught);
}
@Override
public void onSuccess(List<SavedSearch> result) {
- long fetchTime = System.currentTimeMillis() - startTime;
- Log.debug(result.size() + " saved searches fetched in: " + fetchTime + "ms");
-
- ListGrid searchBarPickListGrid = searchBar.getPickListGrid();
- DataSource ds = searchBarPickListGrid.getDataSource();
-
- if (null == ds) {
- ds = new DataSource();
- ds.setClientOnly(true);
- DataSourceTextField valueField = new DataSourceTextField(ATTR_ID, "Id");
- valueField.setPrimaryKey(true);
- ds.setFields(valueField);
- searchBarPickListGrid.setDataSource(ds);
-
- } else {
- ds.invalidateCache();
- }
-
- for (SavedSearch savedSearch : result) {
- Log.debug("savedSearch: " + savedSearch.getName());
- ListGridRecord record = new ListGridRecord();
- record.setAttribute(ATTR_ID, savedSearch.getId());
- record.setAttribute(ATTR_KIND, "Saved");
- record.setAttribute(ATTR_NAME, savedSearch.getName());
- record.setAttribute(ATTR_DESCRIPTION, savedSearch.getDescription());
- record.setAttribute(ATTR_PATTERN, savedSearch.getPattern());
- if (savedSearch.getResultCount() != null)
- record.setAttribute(ATTR_RESULT_COUNT, savedSearch.getResultCount());
- ds.addData(record);
- }
-
try {
- searchBarPickListGrid.setData(new ListGridRecord[] {});
- searchBarPickListGrid.fetchData();
- } catch (Exception e) {
- Log.debug("Caught exception on fetchData: " + e);
+ long fetchTime = System.currentTimeMillis() - startTime;
+ Log.debug(result.size() + " saved searches fetched in: " + fetchTime + "ms");
+
+ ListGrid searchBarPickListGrid = searchBar.getPickListGrid();
+ DataSource ds = searchBarPickListGrid.getDataSource();
+
+ if (null == ds) {
+ ds = new DataSource();
+ ds.setClientOnly(true);
+ DataSourceTextField valueField = new DataSourceTextField(ATTR_ID, "Id");
+ valueField.setPrimaryKey(true);
+ ds.setFields(valueField);
+ searchBarPickListGrid.setDataSource(ds);
+
+ } else {
+ ds.invalidateCache();
+ }
+
+ for (SavedSearch savedSearch : result) {
+ Log.debug("savedSearch: " + savedSearch.getName());
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute(ATTR_ID, savedSearch.getId());
+ record.setAttribute(ATTR_KIND, "Saved");
+ record.setAttribute(ATTR_NAME, savedSearch.getName());
+ record.setAttribute(ATTR_DESCRIPTION, savedSearch.getDescription());
+ record.setAttribute(ATTR_PATTERN, savedSearch.getPattern());
+ if (savedSearch.getResultCount() != null)
+ record.setAttribute(ATTR_RESULT_COUNT, savedSearch.getResultCount());
+ ds.addData(record);
+ }
+
+ try {
+ searchBarPickListGrid.setData(new ListGridRecord[] {});
+ searchBarPickListGrid.fetchData();
+ } catch (Exception e) {
+ Log.debug("Caught exception on fetchData: " + e);
+ }
+ } finally {
+ isSearchInProgress = false;
}
}
});