modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/SearchBarItem.java | 3 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SearchGWTService.java | 4 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/AbstractSearchBar.java | 5 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/FlexSearchBar.java | 250 ++++++---- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java | 189 +++++-- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/favorites/SavedSearchGrid.java | 102 ++-- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/favorites/SavedSearchManager.java | 193 ------- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SearchGWTServiceImpl.java | 26 + 8 files changed, 387 insertions(+), 385 deletions(-)
New commits: commit e175e00b35862e8235c75323c04f28ef1c8820ec Author: Joseph Marques joseph@redhat.com Date: Mon Jan 3 14:22:43 2011 -0500
various SearchBar improvements
* remove use of client-side cache of user's saved search patterns (SavedSearchManager) in favor of direct callouts to SearchGWTService whenever the user's saved search patterns needed to be displayed (read) operated on (create/update/delete). ** this was done for both SearchBar implementations * integrate FlexSearchBar with CoreGUI error/message handling, so that the user gets feedback on every CRUD operation for his/her saved searches
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/SearchBarItem.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/SearchBarItem.java index 83793e4..2f1e950 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/SearchBarItem.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/SearchBarItem.java @@ -35,8 +35,7 @@ public class SearchBarItem extends CanvasItem { public SearchBarItem(String name, String title, SearchSubsystem subsystem) { super(name, title);
- searchBar = new FlexSearchBar(); - searchBar.setSearchSubsystem(subsystem); + searchBar = new FlexSearchBar(subsystem);
searchBar.setHeight("30px"); canvas.addChild(searchBar); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SearchGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SearchGWTService.java index 5ea5641..8dcfae7 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SearchGWTService.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SearchGWTService.java @@ -46,7 +46,9 @@ public interface SearchGWTService extends RemoteService { */ int createSavedSearch(SavedSearch savedSearch) throws RuntimeException;
- void updateSavedSearch(SavedSearch savedSearch) throws RuntimeException; + void updateSavedSearchName(int savedSearchId, final String newName) throws RuntimeException; + + void updateSavedSearchPattern(int savedSearchId, final String newPattern) throws RuntimeException;
void deleteSavedSearch(int savedSearchId) throws RuntimeException;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/AbstractSearchBar.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/AbstractSearchBar.java index a0d44db..7758c4a 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/AbstractSearchBar.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/AbstractSearchBar.java @@ -21,7 +21,6 @@ package org.rhq.enterprise.gui.coregui.client.search; import com.google.gwt.user.client.ui.Composite;
import org.rhq.core.domain.search.SearchSubsystem; -import org.rhq.enterprise.gui.coregui.client.search.favorites.SavedSearchManager;
/** * Abstract class for SearchBar, so that a separate implementation can be written alongside the original. @@ -35,8 +34,4 @@ public abstract class AbstractSearchBar extends Composite { public abstract String getSelectedTab();
public abstract void activateSavedSearch(String savedSearchName); - - public abstract void onSavedSearchManagerLoaded(); - - public abstract SavedSearchManager getSavedSearchManager(); } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/FlexSearchBar.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/FlexSearchBar.java index 2284b78..5af90c6 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/FlexSearchBar.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/FlexSearchBar.java @@ -18,6 +18,8 @@ */ package org.rhq.enterprise.gui.coregui.client.search;
+import java.util.List; + import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; @@ -34,6 +36,7 @@ import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.event.dom.client.MouseOverHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; @@ -41,14 +44,19 @@ import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.TextBox;
+import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.criteria.SavedSearchCriteria; import org.rhq.core.domain.search.SavedSearch; import org.rhq.core.domain.search.SearchSubsystem; import org.rhq.enterprise.gui.coregui.client.CoreGUI; import org.rhq.enterprise.gui.coregui.client.Messages; +import org.rhq.enterprise.gui.coregui.client.UserSessionManager; +import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.search.favorites.SavedSearchGrid; -import org.rhq.enterprise.gui.coregui.client.search.favorites.SavedSearchManager; -import org.rhq.enterprise.gui.coregui.client.search.favorites.SavedSearchGrid.PatternSelectionHandler; +import org.rhq.enterprise.gui.coregui.client.search.favorites.SavedSearchGrid.SavedSearchSelectionHandler; import org.rhq.enterprise.gui.coregui.client.search.suggest.SuggestTextBox_v3; +import org.rhq.enterprise.gui.coregui.client.util.message.Message; +import org.rhq.enterprise.gui.coregui.client.util.message.Message.Severity;
/** * @author Joseph Marques @@ -79,12 +87,11 @@ public class FlexSearchBar extends AbstractSearchBar { private final Image arrowImage = new Image(ARROW_WHITE_URL);
private final PopupPanel savedSearchesPanel = new PopupPanel(true); - private final SavedSearchGrid savedSearchesGrid = new SavedSearchGrid(this); + private SavedSearchGrid savedSearchesGrid;
- private String currentSearch = ""; + private Integer currentSearchId = 0; private long lastNameFieldBlurTime = 0;
- private final SavedSearchManager savedSearchManager; private SearchSubsystem searchSubsystem; private String defaultSearchText; private String defaultSavedSearchPatternId; @@ -102,9 +109,25 @@ public class FlexSearchBar extends AbstractSearchBar { HorizontalPanel sbc_pfsc; HorizontalPanel sbc_ssc;
- public FlexSearchBar() { + private HorizontalPanel createHPanel(Panel parent, String className, String id) { + HorizontalPanel panel = new HorizontalPanel(); + if (parent != null) { + parent.add(panel); + } + if (className != null) { + panel.setStyleName(className); + } + if (id != null) { + panel.getElement().setId(id); + } + return panel; + } + + public FlexSearchBar(SearchSubsystem searchSubsystem) { Log.info("Loading SearchBar...");
+ this.searchSubsystem = searchSubsystem; + this.savedSearchesGrid = new SavedSearchGrid(searchSubsystem); // TODO: load default saved search pattern, if used has selected one // populate default search text // ensure that search subsystem is selected, probably want to force it to be a ctor argument @@ -131,24 +154,6 @@ public class FlexSearchBar extends AbstractSearchBar {
initWidget(sbc);
- savedSearchManager = new SavedSearchManager(this); - } - - private HorizontalPanel createHPanel(Panel parent, String className, String id) { - HorizontalPanel panel = new HorizontalPanel(); - if (parent != null) { - parent.add(panel); - } - if (className != null) { - panel.setStyleName(className); - } - if (id != null) { - panel.getElement().setId(id); - } - return panel; - } - - public void onSavedSearchManagerLoaded() { setupAutoCompletingPatternField(); setupPatternNameField(); setupPatternNameLabel(); @@ -166,16 +171,6 @@ public class FlexSearchBar extends AbstractSearchBar { this.autoCompletePatternField.setText(MSG.view_searchBar_error_selectSavedSearch()); } } - - // presume the enclosing page logic loads results without a button click - } - - public SavedSearchManager getSavedSearchManager() { - return savedSearchManager; - } - - public void setSearchSubsystem(SearchSubsystem searchSubsystem) { - this.searchSubsystem = searchSubsystem; }
public SearchSubsystem getSearchSubsystem() { @@ -257,7 +252,7 @@ public class FlexSearchBar extends AbstractSearchBar {
SavedSearchesEventHandler handler = new SavedSearchesEventHandler(); savedSearchesPanel.addCloseHandler(handler); - savedSearchesGrid.setPatternSelectionHandler(handler); + savedSearchesGrid.setSavedSearchSelectionHandler(handler); }
private void turnNameFieldIntoLabel() { @@ -271,26 +266,35 @@ public class FlexSearchBar extends AbstractSearchBar { patternNameField.setVisible(false);
if (name.equals("")) { - savedSearchManager.removePatternByName(currentSearch); + GWTServiceLookup.getSearchService().deleteSavedSearch(currentSearchId, new AsyncCallback<Void>() { + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError("Saved search removal failed", caught); + } + + @Override + public void onSuccess(Void result) { + CoreGUI.getMessageCenter().notify(new Message("Removed saved search successfully", Severity.Info)); + } + }); + starImage.setUrl(STAR_OFF_URL); } else { - if (currentSearch.equals("")) { + // NOTE: currently do not support updated a saved search pattern + if (currentSearchId == 0) { String pattern = autoCompletePatternField.getText(); - savedSearchManager.updatePatternByName(name, pattern); // create case + createSavedSearch(name, pattern); } else { - savedSearchManager.renamePattern(currentSearch, name); + updateSavedSearchName(currentSearchId, name); } - //savedSearchManager.updatePatternByName(name, pattern); patternNameLabel.setText(elipse(name)); patternNameLabel.setVisible(true); starImage.setUrl(STAR_ON_URL); } - currentSearch = name; }
private void turnNameLabelIntoField() { - String name = currentSearch; - patternNameField.setText(name); + patternNameField.setText(patternNameLabel.getText()); patternNameField.setVisible(true); patternNameLabel.setVisible(false); patternNameField.setFocus(true); @@ -303,6 +307,37 @@ public class FlexSearchBar extends AbstractSearchBar { return data; }
+ private void createSavedSearch(final String name, final String pattern) { + Subject subject = UserSessionManager.getSessionSubject(); + SavedSearch newSavedSearch = new SavedSearch(searchSubsystem, name, pattern, subject); + GWTServiceLookup.getSearchService().createSavedSearch(newSavedSearch, new AsyncCallback<Integer>() { + @Override + public void onSuccess(Integer newSavedSearchId) { + CoreGUI.getMessageCenter().notify(new Message("Saved search created successfully", Severity.Info)); + currentSearchId = newSavedSearchId; + } + + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError("Saved search creation failed", caught); + } + }); + } + + private void updateSavedSearchName(final int savedSearchId, final String newName) { + GWTServiceLookup.getSearchService().updateSavedSearchName(savedSearchId, newName, new AsyncCallback<Void>() { + @Override + public void onSuccess(Void result) { + CoreGUI.getMessageCenter().notify(new Message("Saved search successfully renamed", Severity.Info)); + } + + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError("Saved search rename failed", caught); + } + }); + } + /* * Event Handlers */ @@ -317,7 +352,7 @@ public class FlexSearchBar extends AbstractSearchBar { patternNameLabel.setVisible(false); patternNameField.setValue("", true); patternNameField.setVisible(false); - currentSearch = ""; + currentSearchId = 0; starImage.setUrl(STAR_OFF_URL);
if (event.getCharCode() == KeyCodes.KEY_ESCAPE) { @@ -390,7 +425,17 @@ public class FlexSearchBar extends AbstractSearchBar { starImage.setUrl(STAR_ACTIVE_URL); patternNameField.setVisible(false); patternNameLabel.setVisible(false); - savedSearchManager.removePatternByName(currentSearch); + GWTServiceLookup.getSearchService().deleteSavedSearch(currentSearchId, new AsyncCallback<Void>() { + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError("Saved search deletion failure", caught); + } + + @Override + public void onSuccess(Void result) { + CoreGUI.getMessageCenter().notify(new Message("Saved search deletion success", Severity.Info)); + } + }); } }
@@ -410,68 +455,101 @@ public class FlexSearchBar extends AbstractSearchBar {
class ArrowImageEventHandler implements ClickHandler { public void onClick(ClickEvent event) { - savedSearchesGrid.updateModel(); - int left = autoCompletePatternField.getAbsoluteLeft(); - int top = autoCompletePatternField.getAbsoluteTop() + autoCompletePatternField.getOffsetHeight(); - savedSearchesPanel.setPopupPosition(left, top + 5); - savedSearchesPanel.show(); - arrowImage.setUrl(ARROW_GRAY_URL); + savedSearchesGrid.updateModel(new AsyncCallback<List<SavedSearch>>() { + @Override + public void onFailure(Throwable caught) { + // nothing needs to be done + } + + @Override + public void onSuccess(List<SavedSearch> updatedGridData) { + int left = autoCompletePatternField.getAbsoluteLeft(); + int top = autoCompletePatternField.getAbsoluteTop() + autoCompletePatternField.getOffsetHeight(); + savedSearchesPanel.setPopupPosition(left, top + 5); + savedSearchesPanel.show(); + arrowImage.setUrl(ARROW_GRAY_URL); + } + }); } }
- class SavedSearchesEventHandler implements CloseHandler<PopupPanel>, PatternSelectionHandler { + class SavedSearchesEventHandler implements CloseHandler<PopupPanel>, SavedSearchSelectionHandler { public void onClose(CloseEvent<PopupPanel> event) { arrowImage.setUrl(ARROW_WHITE_URL); }
- public void handleSelection(int rowIndex, int columnIndex, String patternName) { - Log.debug("SavedSearchesEventHandler.handleSelection(" + rowIndex + "," + columnIndex + "," + patternName + public void handleSelection(final int rowIndex, final int columnIndex, final SavedSearch savedSearch) { + Log.debug("SavedSearchesEventHandler.handleSelection(" + rowIndex + "," + columnIndex + "," + savedSearch + ")"); if (columnIndex == 1) { - savedSearchManager.removePatternByName(patternName); - - if (currentSearch.equals(patternName)) { - currentSearch = ""; - patternNameField.setValue("", true); - patternNameField.setVisible(false); - patternNameLabel.setText(""); - patternNameLabel.setVisible(false); - autoCompletePatternField.setFocus(true); - starImage.setUrl(STAR_OFF_URL); - savedSearchesPanel.hide(); - } - - if (savedSearchManager.getSavedSearchCount() == 0) { - savedSearchesPanel.hide(); - } - - savedSearchesGrid.removeRow(rowIndex); + GWTServiceLookup.getSearchService().deleteSavedSearch(savedSearch.getId(), new AsyncCallback<Void>() { + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError("Saved search deletion failure", caught); + } + + @Override + public void onSuccess(Void result) { + if (currentSearchId == savedSearch.getId()) { + currentSearchId = 0; + patternNameField.setValue("", true); + patternNameField.setVisible(false); + patternNameLabel.setText(""); + patternNameLabel.setVisible(false); + autoCompletePatternField.setFocus(true); + starImage.setUrl(STAR_OFF_URL); + savedSearchesPanel.hide(); + } + + // is user deleting the one and only element in the list? + if (savedSearchesGrid.size() == 1) { + savedSearchesPanel.hide(); + } + savedSearchesGrid.removeRow(rowIndex); + } + }); } else { - activateSavedSearch(patternName); // activating the saved search also clicks the button + activateSavedSearch(savedSearch); // activating the saved search also clicks the button } } }
public void activateSavedSearch(Integer savedSearchId) { - SavedSearch savedSearch = savedSearchManager.getSavedSearchById(savedSearchId); - if (savedSearch == null) { - Log.debug("activateSavedSearch: no known saved search with id '" + savedSearchId + "'"); - return; // no saved search existing with the specified id - } - activateSavedSearch(savedSearch); + activeSavedSearchByIdOrName(savedSearchId, null); }
public void activateSavedSearch(String savedSearchName) { - SavedSearch savedSearch = savedSearchManager.getSavedSearchByName(savedSearchName); - if (savedSearch == null) { - Log.debug("activateSavedSearch: no known saved search with name '" + savedSearchName + "'"); - return; // no saved search existing with the specified name - } - activateSavedSearch(savedSearch); + activeSavedSearchByIdOrName(null, savedSearchName); + } + + private void activeSavedSearchByIdOrName(Integer savedSearchId, String savedSearchName) { + Subject subject = UserSessionManager.getSessionSubject(); + SavedSearchCriteria criteria = new SavedSearchCriteria(); + criteria.addFilterSubjectId(subject.getId()); + criteria.addFilterId(savedSearchId); // null OK + criteria.addFilterName(savedSearchName); // null OK + + GWTServiceLookup.getSearchService().findSavedSearchesByCriteria(criteria, + new AsyncCallback<List<SavedSearch>>() { + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError("Failure to select saved search", caught); + } + + @Override + public void onSuccess(List<SavedSearch> results) { + if (results.size() != 1) { + CoreGUI.getMessageCenter().notify(new Message("Error selecting saved search", Severity.Error)); + } else { + SavedSearch savedSearch = results.get(0); + activateSavedSearch(savedSearch); + } + } + }); }
public void activateSavedSearch(SavedSearch savedSearch) { - currentSearch = ""; + currentSearchId = savedSearch.getId(); autoCompletePatternField.setValue(savedSearch.getPattern(), true); patternNameField.setValue(savedSearch.getName(), true); Log.debug("search results change: [" + savedSearch.getName() + "," + savedSearch.getPattern() + "]"); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java index b421132..af2ef0e 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/SearchBar.java @@ -18,6 +18,8 @@ */ package org.rhq.enterprise.gui.coregui.client.search;
+import java.util.List; + import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; @@ -39,20 +41,26 @@ import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.Event.NativePreviewHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.TextBox;
+import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.criteria.SavedSearchCriteria; import org.rhq.core.domain.search.SavedSearch; import org.rhq.core.domain.search.SearchSubsystem; import org.rhq.enterprise.gui.coregui.client.CoreGUI; import org.rhq.enterprise.gui.coregui.client.Messages; +import org.rhq.enterprise.gui.coregui.client.UserSessionManager; +import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.search.favorites.SavedSearchGrid; -import org.rhq.enterprise.gui.coregui.client.search.favorites.SavedSearchManager; -import org.rhq.enterprise.gui.coregui.client.search.favorites.SavedSearchGrid.PatternSelectionHandler; +import org.rhq.enterprise.gui.coregui.client.search.favorites.SavedSearchGrid.SavedSearchSelectionHandler; import org.rhq.enterprise.gui.coregui.client.search.suggest.SuggestTextBox_v3; +import org.rhq.enterprise.gui.coregui.client.util.message.Message; +import org.rhq.enterprise.gui.coregui.client.util.message.Message.Severity;
/** * @author Joseph Marques @@ -83,12 +91,11 @@ public class SearchBar extends AbstractSearchBar { private final Image arrowImage = new Image(ARROW_WHITE_URL);
private final PopupPanel savedSearchesPanel = new PopupPanel(true); - private final SavedSearchGrid savedSearchesGrid = new SavedSearchGrid(this); + private SavedSearchGrid savedSearchesGrid;
- private String currentSearch = ""; + private Integer currentSearchId = 0; private long lastNameFieldBlurTime = 0;
- private final SavedSearchManager savedSearchManager; private SearchSubsystem searchSubsystem; private String defaultSearchText; private String defaultSavedSearchPatternId; @@ -96,6 +103,18 @@ public class SearchBar extends AbstractSearchBar {
private Element searchButton;
+ private AsyncCallback<Void> blackHoleCallback = new AsyncCallback<Void>() { + @Override + public void onFailure(Throwable caught) { + // old search bar can't access CoreGUI.getErrorHandler(), silently ignore the error + } + + @Override + public void onSuccess(Void result) { + // old search bar can't access CoreGUI.getMessageCenter(), silently continue with success path + } + }; + public static boolean existsOnPage() { return getSearchBarElement() != null; } @@ -149,10 +168,6 @@ public class SearchBar extends AbstractSearchBar { loadAdditionalDataFromDivAttributes(); }
- savedSearchManager = new SavedSearchManager(this); - } - - public void onSavedSearchManagerLoaded() { RootPanel.get("patternFieldContainer").add(autoCompletePatternField); RootPanel.get("patternNameFieldContainer").add(patternNameField); RootPanel.get("patternNameLabelContainer").add(patternNameLabel); @@ -184,12 +199,9 @@ public class SearchBar extends AbstractSearchBar { // presume the enclosing page logic loads results without a button click }
- public SavedSearchManager getSavedSearchManager() { - return savedSearchManager; - } - public void setSearchSubsystem(SearchSubsystem searchSubsystem) { this.searchSubsystem = searchSubsystem; + savedSearchesGrid = new SavedSearchGrid(searchSubsystem); }
public SearchSubsystem getSearchSubsystem() { @@ -275,7 +287,7 @@ public class SearchBar extends AbstractSearchBar {
SavedSearchesEventHandler handler = new SavedSearchesEventHandler(); savedSearchesPanel.addCloseHandler(handler); - savedSearchesGrid.setPatternSelectionHandler(handler); + savedSearchesGrid.setSavedSearchSelectionHandler(handler); }
private void turnNameFieldIntoLabel() { @@ -289,26 +301,24 @@ public class SearchBar extends AbstractSearchBar { patternNameField.setVisible(false);
if (name.equals("")) { - savedSearchManager.removePatternByName(currentSearch); + GWTServiceLookup.getSearchService().deleteSavedSearch(currentSearchId, blackHoleCallback); starImage.setUrl(STAR_OFF_URL); } else { - if (currentSearch.equals("")) { + // NOTE: currently do not support updated a saved search pattern + if (currentSearchId == 0) { String pattern = autoCompletePatternField.getText(); - savedSearchManager.updatePatternByName(name, pattern); // create case + createSavedSearch(name, pattern); } else { - savedSearchManager.renamePattern(currentSearch, name); + updateSavedSearchName(currentSearchId, name); } - //savedSearchManager.updatePatternByName(name, pattern); patternNameLabel.setText(elipse(name)); patternNameLabel.setVisible(true); starImage.setUrl(STAR_ON_URL); } - currentSearch = name; }
private void turnNameLabelIntoField() { - String name = currentSearch; - patternNameField.setText(name); + patternNameField.setText(patternNameLabel.getText()); patternNameField.setVisible(true); patternNameLabel.setVisible(false); patternNameField.setFocus(true); @@ -321,6 +331,25 @@ public class SearchBar extends AbstractSearchBar { return data; }
+ private void createSavedSearch(final String name, final String pattern) { + Subject subject = UserSessionManager.getSessionSubject(); + SavedSearch newSavedSearch = new SavedSearch(searchSubsystem, name, pattern, subject); + GWTServiceLookup.getSearchService().createSavedSearch(newSavedSearch, new AsyncCallback<Integer>() { + @Override + public void onSuccess(Integer newSavedSearchId) { + currentSearchId = newSavedSearchId; + } + + @Override + public void onFailure(Throwable caught) { + } + }); + } + + private void updateSavedSearchName(final int savedSearchId, final String newName) { + GWTServiceLookup.getSearchService().updateSavedSearchName(savedSearchId, newName, blackHoleCallback); + } + /* * Event Handlers */ @@ -335,7 +364,7 @@ public class SearchBar extends AbstractSearchBar { patternNameLabel.setVisible(false); patternNameField.setValue("", true); patternNameField.setVisible(false); - currentSearch = ""; + currentSearchId = 0; starImage.setUrl(STAR_OFF_URL);
if (event.getCharCode() == KeyCodes.KEY_ESCAPE) { @@ -408,7 +437,7 @@ public class SearchBar extends AbstractSearchBar { starImage.setUrl(STAR_ACTIVE_URL); patternNameField.setVisible(false); patternNameLabel.setVisible(false); - savedSearchManager.removePatternByName(currentSearch); + GWTServiceLookup.getSearchService().deleteSavedSearch(currentSearchId, blackHoleCallback); } }
@@ -428,44 +457,60 @@ public class SearchBar extends AbstractSearchBar {
class ArrowImageEventHandler implements ClickHandler { public void onClick(ClickEvent event) { - savedSearchesGrid.updateModel(); - int left = autoCompletePatternField.getAbsoluteLeft(); - int top = autoCompletePatternField.getAbsoluteTop() + autoCompletePatternField.getOffsetHeight(); - savedSearchesPanel.setPopupPosition(left, top + 5); - savedSearchesPanel.show(); - arrowImage.setUrl(ARROW_GRAY_URL); + savedSearchesGrid.updateModel(new AsyncCallback<List<SavedSearch>>() { + @Override + public void onFailure(Throwable caught) { + // nothing needs to be done + } + + @Override + public void onSuccess(List<SavedSearch> updatedGridData) { + int left = autoCompletePatternField.getAbsoluteLeft(); + int top = autoCompletePatternField.getAbsoluteTop() + autoCompletePatternField.getOffsetHeight(); + savedSearchesPanel.setPopupPosition(left, top + 5); + savedSearchesPanel.show(); + arrowImage.setUrl(ARROW_GRAY_URL); + } + }); } }
- class SavedSearchesEventHandler implements CloseHandler<PopupPanel>, PatternSelectionHandler { + class SavedSearchesEventHandler implements CloseHandler<PopupPanel>, SavedSearchSelectionHandler { public void onClose(CloseEvent<PopupPanel> event) { arrowImage.setUrl(ARROW_WHITE_URL); }
- public void handleSelection(int rowIndex, int columnIndex, String patternName) { - Log.debug("SavedSearchesEventHandler.handleSelection(" + rowIndex + "," + columnIndex + "," + patternName + public void handleSelection(final int rowIndex, final int columnIndex, final SavedSearch savedSearch) { + Log.debug("SavedSearchesEventHandler.handleSelection(" + rowIndex + "," + columnIndex + "," + savedSearch + ")"); if (columnIndex == 1) { - savedSearchManager.removePatternByName(patternName); - - if (currentSearch.equals(patternName)) { - currentSearch = ""; - patternNameField.setValue("", true); - patternNameField.setVisible(false); - patternNameLabel.setText(""); - patternNameLabel.setVisible(false); - autoCompletePatternField.setFocus(true); - starImage.setUrl(STAR_OFF_URL); - savedSearchesPanel.hide(); - } - - if (savedSearchManager.getSavedSearchCount() == 0) { - savedSearchesPanel.hide(); - } + GWTServiceLookup.getSearchService().deleteSavedSearch(savedSearch.getId(), new AsyncCallback<Void>() { + @Override + public void onFailure(Throwable caught) { + }
- savedSearchesGrid.removeRow(rowIndex); + @Override + public void onSuccess(Void result) { + if (currentSearchId == savedSearch.getId()) { + currentSearchId = 0; + patternNameField.setValue("", true); + patternNameField.setVisible(false); + patternNameLabel.setText(""); + patternNameLabel.setVisible(false); + autoCompletePatternField.setFocus(true); + starImage.setUrl(STAR_OFF_URL); + savedSearchesPanel.hide(); + } + + // is user deleting the one and only element in the list? + if (savedSearchesGrid.size() == 1) { + savedSearchesPanel.hide(); + } + savedSearchesGrid.removeRow(rowIndex); + } + }); } else { - activateSavedSearch(patternName); // activating the saved search also clicks the button + activateSavedSearch(savedSearch); // activating the saved search also clicks the button } } } @@ -476,25 +521,41 @@ public class SearchBar extends AbstractSearchBar { }-*/;
public void activateSavedSearch(Integer savedSearchId) { - SavedSearch savedSearch = savedSearchManager.getSavedSearchById(savedSearchId); - if (savedSearch == null) { - Log.debug("activateSavedSearch: no known saved search with id '" + savedSearchId + "'"); - return; // no saved search existing with the specified id - } - activateSavedSearch(savedSearch); + activeSavedSearchByIdOrName(savedSearchId, null); }
public void activateSavedSearch(String savedSearchName) { - SavedSearch savedSearch = savedSearchManager.getSavedSearchByName(savedSearchName); - if (savedSearch == null) { - Log.debug("activateSavedSearch: no known saved search with name '" + savedSearchName + "'"); - return; // no saved search existing with the specified name - } - activateSavedSearch(savedSearch); + activeSavedSearchByIdOrName(null, savedSearchName); + } + + private void activeSavedSearchByIdOrName(Integer savedSearchId, String savedSearchName) { + Subject subject = UserSessionManager.getSessionSubject(); + SavedSearchCriteria criteria = new SavedSearchCriteria(); + criteria.addFilterSubjectId(subject.getId()); + criteria.addFilterId(savedSearchId); // null OK + criteria.addFilterName(savedSearchName); // null OK + + GWTServiceLookup.getSearchService().findSavedSearchesByCriteria(criteria, + new AsyncCallback<List<SavedSearch>>() { + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError("Failure to select saved search", caught); + } + + @Override + public void onSuccess(List<SavedSearch> results) { + if (results.size() != 1) { + CoreGUI.getMessageCenter().notify(new Message("Error selecting saved search", Severity.Error)); + } else { + SavedSearch savedSearch = results.get(0); + activateSavedSearch(savedSearch); + } + } + }); }
public void activateSavedSearch(SavedSearch savedSearch) { - currentSearch = ""; + currentSearchId = savedSearch.getId(); autoCompletePatternField.setValue(savedSearch.getPattern(), true); patternNameField.setValue(savedSearch.getName(), true); Log.debug("search results change: [" + savedSearch.getName() + "," + savedSearch.getPattern() + "]"); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/favorites/SavedSearchGrid.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/favorites/SavedSearchGrid.java index 188cd89..f0e72c3 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/favorites/SavedSearchGrid.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/favorites/SavedSearchGrid.java @@ -18,16 +18,23 @@ */ package org.rhq.enterprise.gui.coregui.client.search.favorites;
+import java.util.ArrayList; import java.util.List;
-import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Grid;
+import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.criteria.SavedSearchCriteria; import org.rhq.core.domain.search.SavedSearch; -import org.rhq.enterprise.gui.coregui.client.search.AbstractSearchBar; +import org.rhq.core.domain.search.SearchSubsystem; +import org.rhq.core.domain.util.PageOrdering; +import org.rhq.enterprise.gui.coregui.client.CoreGUI; +import org.rhq.enterprise.gui.coregui.client.UserSessionManager; +import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.search.SearchBar;
/** @@ -35,21 +42,33 @@ import org.rhq.enterprise.gui.coregui.client.search.SearchBar; */ public class SavedSearchGrid extends Grid {
- private PatternSelectionHandler patternSelectionHandler; - private AbstractSearchBar searchBar; + private SavedSearchSelectionHandler patternSelectionHandler; + private SearchSubsystem searchSubsystem; + private List<SavedSearch> data = new ArrayList<SavedSearch>();
- public interface PatternSelectionHandler { - public void handleSelection(int rowIndex, int columnIndex, String patternName); + public interface SavedSearchSelectionHandler { + public void handleSelection(int rowIndex, int columnIndex, SavedSearch savedSearch); }
- public void setPatternSelectionHandler(PatternSelectionHandler handler) { + public void setSavedSearchSelectionHandler(SavedSearchSelectionHandler handler) { this.patternSelectionHandler = handler; }
class SavedSearchRowFormatter extends RowFormatter { + private int savedSearchCount; + + public SavedSearchRowFormatter() { + this(0); + } + + public SavedSearchRowFormatter(int savedSearchCount) { + this.savedSearchCount = savedSearchCount; + } + @Override public String getStyleName(int row) { - if (row < count()) { + // add -bottom decoration for all rows except last + if (row < savedSearchCount) { return " savedSearchesPanel-row"; } return ""; @@ -61,7 +80,7 @@ public class SavedSearchGrid extends Grid { } }
- public SavedSearchGrid(AbstractSearchBar searchBar) { + public SavedSearchGrid(SearchSubsystem searchSubsystem) { super(0, 2); // assume no rows to start, but we'll always have 2 columns
setRowFormatter(new SavedSearchRowFormatter()); @@ -70,7 +89,7 @@ public class SavedSearchGrid extends Grid { setCellPadding(5); setStyleName("savedSearchesGrid");
- this.searchBar = searchBar; + this.searchSubsystem = searchSubsystem; }
@Override @@ -85,12 +104,8 @@ public class SavedSearchGrid extends Grid { case Event.ONCLICK: { int columnIndex = DOM.getChildIndex(tr, td); int rowIndex = DOM.getChildIndex(table, tr); - String text = getHTML(rowIndex, 0); - int startIndex = text.indexOf('>') + 1; - int endIndex = text.toLowerCase().indexOf("</span>", startIndex); - String patternName = text.substring(startIndex, endIndex); - Log.debug("Selected '" + patternName + " at row=" + rowIndex + ", col=" + columnIndex); - patternSelectionHandler.handleSelection(rowIndex, columnIndex, patternName); + SavedSearch savedSearch = data.get(rowIndex); // get request-cached element that should be in that row + patternSelectionHandler.handleSelection(rowIndex, columnIndex, savedSearch); if (columnIndex == 0) { onRowOut(tr); } @@ -123,19 +138,40 @@ public class SavedSearchGrid extends Grid { DOM.setStyleAttribute(row, "backgroundColor", "rgb(222,222,222)"); }
- public void updateModel() { - List<String> names = searchBar.getSavedSearchManager().getPatternNamesMRU(); - - clear(true); - resizeRows(names.size()); - - for (int i = 0; i < names.size(); i++) { - String name = names.get(i); - SavedSearch savedSearch = searchBar.getSavedSearchManager().getSavedSearchByName(name); - setHTML(i, 0, stylize(savedSearch)); - setHTML(i, 1, trashify()); - } - setRowFormatter(new SavedSearchRowFormatter()); + public void updateModel(final AsyncCallback<List<SavedSearch>> callback) { + Subject subject = UserSessionManager.getSessionSubject(); + SavedSearchCriteria criteria = new SavedSearchCriteria(); + criteria.addFilterSubjectId(subject.getId()); + criteria.addFilterSearchSubsystem(searchSubsystem); + criteria.addSortName(PageOrdering.ASC); + + GWTServiceLookup.getSearchService().findSavedSearchesByCriteria(criteria, + new AsyncCallback<List<SavedSearch>>() { + @Override + public void onSuccess(List<SavedSearch> userSavedSearches) { + data = userSavedSearches; // cache for correct client-side lookup on selection event + clear(true); + resizeRows(userSavedSearches.size()); + + int i = 0; + SavedSearchRowFormatter rowFormatter = new SavedSearchRowFormatter(data.size()); + for (SavedSearch nextSavedSearch : userSavedSearches) { + setHTML(i, 0, stylize(nextSavedSearch)); + setHTML(i, 1, trashify()); + i++; + } + setRowFormatter(rowFormatter); + + callback.onSuccess(userSavedSearches); + } + + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError("Could not load saved searches", caught); + + callback.onFailure(caught); + } + }); }
private static String stylize(SavedSearch savedSearch) { @@ -150,11 +186,11 @@ public class SavedSearchGrid extends Grid { return "<div name="action"></div>"; }
- private int count() { - return searchBar.getSavedSearchManager().getSavedSearchCount(); - } - public String getSelectedItem() { return ""; } + + public int size() { + return data.size(); + } } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/favorites/SavedSearchManager.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/favorites/SavedSearchManager.java deleted file mode 100644 index b6ec717..0000000 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/search/favorites/SavedSearchManager.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2010 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package org.rhq.enterprise.gui.coregui.client.search.favorites; - -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; - -import com.allen_sauer.gwt.log.client.Log; -import com.google.gwt.user.client.rpc.AsyncCallback; - -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.criteria.SavedSearchCriteria; -import org.rhq.core.domain.search.SavedSearch; -import org.rhq.enterprise.gui.coregui.client.UserSessionManager; -import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; -import org.rhq.enterprise.gui.coregui.client.gwt.SearchGWTServiceAsync; -import org.rhq.enterprise.gui.coregui.client.search.AbstractSearchBar; - -/** - * @author Joseph Marques - */ -public class SavedSearchManager { - - private final SearchGWTServiceAsync searchService = GWTServiceLookup.getSearchService(); - - private LinkedHashMap<String, SavedSearch> savedSearches = new LinkedHashMap<String, SavedSearch>(); - private AbstractSearchBar searchBar; - - public SavedSearchManager(AbstractSearchBar searchBar) { - this.searchBar = searchBar; - load(); - } - - public synchronized String getPatternByName(String name) { - SavedSearch savedSearch = savedSearches.get(name); - if (savedSearch == null) { - return null; - } - return savedSearch.getPattern(); - } - - public synchronized SavedSearch getSavedSearchByName(String name) { - return savedSearches.get(name); - } - - public synchronized SavedSearch getSavedSearchById(Integer savedSearchId) { - for (SavedSearch next : savedSearches.values()) { - if (next.getId().equals(savedSearchId)) { - return next; - } - } - return null; - } - - public synchronized void updatePatternByName(final String name, final String pattern) { - SavedSearch savedSearch = savedSearches.get(name); - if (savedSearch == null) { // created case - final SavedSearch newSavedSearch = new SavedSearch(searchBar.getSearchSubsystem(), name, pattern, - UserSessionManager.getSessionSubject()); - searchService.createSavedSearch(newSavedSearch, new AsyncCallback<Integer>() { - - public void onFailure(Throwable caught) { - Log.debug("Error: created saved search [" + name + "] with pattern [" + pattern + "]: " - + caught.getMessage()); - } - - public void onSuccess(Integer result) { - newSavedSearch.setId(result); - savedSearches.put(name, newSavedSearch); - } - }); - - } else { // update case - searchService.updateSavedSearch(savedSearch, new AsyncCallback<Void>() { - - public void onFailure(Throwable caught) { - Log.debug("Error: updating saved search [" + name + "] with pattern [" + pattern + "]: " - + caught.getMessage()); - } - - public void onSuccess(Void result) { - SavedSearch savedSearch = savedSearches.remove(name); - savedSearch.setPattern(pattern); - savedSearches.put(name, savedSearch); - } - }); - } - } - - public synchronized List<String> getPatternNamesMRU() { - List<String> results = new LinkedList<String>(); - for (String name : savedSearches.keySet()) { - results.add(0, name); - } - return results; - } - - public synchronized void removePatternByName(final String name) { - SavedSearch savedSearch = savedSearches.get(name); - if (savedSearch == null) { - return; - } - searchService.deleteSavedSearch(savedSearch.getId(), new AsyncCallback<Void>() { - - public void onFailure(Throwable caught) { - Log.debug("Error: removing saved search [" + name + "]: " + caught.getMessage()); - } - - public void onSuccess(Void result) { - savedSearches.remove(name); - } - }); - } - - public synchronized void renamePattern(final String oldName, final String newName) { - final SavedSearch savedSearch = savedSearches.remove(oldName); - if (savedSearch == null) { - return; - } - savedSearch.setName(newName); - savedSearches.put(newName, savedSearch); - searchService.updateSavedSearch(savedSearch, new AsyncCallback<Void>() { - - public void onFailure(Throwable caught) { - savedSearch.setName(oldName); // revive old name because server-side change failed - Log.debug("Error: renaming saved search from [" + oldName + "] to [" + newName + "]: " - + caught.getMessage()); - } - - public void onSuccess(Void result) { - // do nothing, reference was already renamed in-band - } - }); - } - - public synchronized int getSavedSearchCount() { - return savedSearches.size(); - } - - private synchronized void load() { - Subject currentUser = UserSessionManager.getSessionSubject(); - SavedSearchCriteria criteria = new SavedSearchCriteria(); - criteria.addFilterSubjectId(currentUser.getId()); - criteria.addFilterSearchSubsystem(searchBar.getSearchSubsystem()); - searchService.findSavedSearchesByCriteria(criteria, new AsyncCallback<List<SavedSearch>>() { - - public void onSuccess(List<SavedSearch> result) { - try { - savedSearches.clear(); - Collections.sort(result, new Comparator<SavedSearch>() { - - public int compare(SavedSearch first, SavedSearch second) { - return first.getName().compareTo(second.getName()); - } - }); - for (SavedSearch next : result) { - savedSearches.put(next.getName(), next); - } - } finally { - searchBar.onSavedSearchManagerLoaded(); - } - } - - public void onFailure(Throwable caught) { - try { - Log.debug("Error: loading saved searches: " + caught.getMessage()); - } finally { - searchBar.onSavedSearchManagerLoaded(); - } - } - }); - } - -} diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SearchGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SearchGWTServiceImpl.java index c80728e..dc3a069 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SearchGWTServiceImpl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SearchGWTServiceImpl.java @@ -70,8 +70,20 @@ public class SearchGWTServiceImpl extends AbstractGWTServiceImpl implements Sear } }
- public void updateSavedSearch(SavedSearch savedSearch) throws RuntimeException { + public void updateSavedSearchName(int savedSearchId, final String newName) throws RuntimeException { try { + SavedSearch savedSearch = getSubjectSavedSearch(savedSearchId); + savedSearch.setName(newName); + savedSearchManager.updateSavedSearch(getSessionSubject(), savedSearch); + } catch (Throwable t) { + throw new RuntimeException(ThrowableUtil.getAllMessages(t)); + } + } + + public void updateSavedSearchPattern(int savedSearchId, final String newPattern) throws RuntimeException { + try { + SavedSearch savedSearch = getSubjectSavedSearch(savedSearchId); + savedSearch.setPattern(newPattern); savedSearchManager.updateSavedSearch(getSessionSubject(), savedSearch); } catch (Throwable t) { throw new RuntimeException(ThrowableUtil.getAllMessages(t)); @@ -95,4 +107,16 @@ public class SearchGWTServiceImpl extends AbstractGWTServiceImpl implements Sear } }
+ private SavedSearch getSubjectSavedSearch(int savedSearchId) { + SavedSearchCriteria criteria = new SavedSearchCriteria(); + criteria.addFilterSubjectId(getSessionSubject().getId()); // ensure user can only fetch his/her own + criteria.addFilterId(savedSearchId); + List<SavedSearch> results = findSavedSearchesByCriteria(criteria); + if (results.isEmpty()) { + return null; + } else { + return results.get(0); + } + } + } \ No newline at end of file
rhq-commits@lists.fedorahosted.org