modules/core/domain/src/main/java/org/rhq/core/domain/util/StringUtils.java | 44 ++--
modules/core/domain/src/test/java/org/rhq/core/domain/util/StringUtilsTest.java | 47 ++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java | 31 ++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java | 7
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java | 34 ++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ValidationStateChangeListener.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/wizard/AbstractWizard.java | 6
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/wizard/GroupCreateWizard.java | 18 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java | 22 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java | 20 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageBar.java | 102 ++++++++--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java | 7
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java | 71 +++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/TransientMessage.java | 48 ++++
modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css | 14 -
16 files changed, 345 insertions(+), 130 deletions(-)
New commits:
commit 6415ed10e3b0d967b712a7be0aa0a3fcf4ce95cb
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Thu Sep 30 15:40:37 2010 -0400
fix bug in core-domain StringUtils.deCamelCase() and add unit test for that method; add support for transient messages to the message center - transient messages are displayed in the header and generally auto-clear after 30 seconds
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/util/StringUtils.java b/modules/core/domain/src/main/java/org/rhq/core/domain/util/StringUtils.java
index 938b07f..01a6ddb 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/util/StringUtils.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/util/StringUtils.java
@@ -33,8 +33,14 @@ import java.util.Set;
public class StringUtils {
private static final Set<String> LOWERCASE_WORDS = new HashSet<String>();
static {
+ // conjunctions
LOWERCASE_WORDS.add("And");
LOWERCASE_WORDS.add("Or");
+
+ // articles
+ LOWERCASE_WORDS.add("A");
+ LOWERCASE_WORDS.add("An");
+ LOWERCASE_WORDS.add("The");
}
/*
@@ -65,39 +71,47 @@ public class StringUtils {
+ target.substring(nextDash + 2);
}
- StringBuilder currentWord = new StringBuilder();
char currentChar;
- char previousChar = 0;
- for (int i = 0; i < target.length(); i++) {
+ // Always make the first char upper case.
+ char previousChar = Character.toUpperCase(target.charAt(0));
+ StringBuilder currentWord = new StringBuilder();
+ currentWord.append(previousChar);
+ for (int i = 1; i < target.length(); i++) {
currentChar = target.charAt(i);
// Make sure to insert spaces in the middle of acronyms or multi-digit numbers.
- if ((i != 0) &&
- ((Character.isDigit(currentChar) && !Character.isDigit(previousChar))
+ if ((previousChar == ' ' && currentChar != ' ')
+ || (Character.isDigit(currentChar) && !Character.isDigit(previousChar))
|| (Character.isUpperCase(currentChar) && (!Character.isUpperCase(previousChar)
- || ((i < (target.length() - 1)) && Character.isLowerCase(target.charAt(i + 1))))))) {
+ || ((i < (target.length() - 1)) && Character.isLowerCase(target.charAt(i + 1)))))) {
// We're at the start of a new word.
- appendWord(result, currentWord);
+ appendWord(result, currentWord.toString());
currentWord = new StringBuilder();
// Append a space before the next word.
result.append(' ');
}
- currentWord.append(currentChar);
+ if (currentChar != ' ') {
+ currentWord.append(currentChar);
+ }
previousChar = currentChar;
}
// Append the final word.
- appendWord(result, currentWord);
+ appendWord(result, currentWord.toString());
return result.toString();
}
- private static void appendWord(StringBuilder result, StringBuilder nextWord) {
- String word = nextWord.toString();
- if (LOWERCASE_WORDS.contains(word)) {
- result.append(word.toLowerCase());
- } else {
- result.append(word);
+ private static void appendWord(StringBuilder result, String word) {
+ if (word.length() >= 1) {
+ if (LOWERCASE_WORDS.contains(word)) {
+ result.append(word.toLowerCase());
+ } else {
+ result.append(Character.toUpperCase(word.charAt(0)));
+ if (word.length() > 1) {
+ result.append(word.substring(1));
+ }
+ }
}
}
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/util/StringUtilsTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/util/StringUtilsTest.java
new file mode 100644
index 0000000..fde0c6b
--- /dev/null
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/util/StringUtilsTest.java
@@ -0,0 +1,47 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * 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.core.domain.util;
+
+import static org.testng.Assert.*;
+
+import org.testng.annotations.Test;
+
+/**
+ * Tests for {@link StringUtils}.
+ *
+ * @author Ian Springer
+ */
+public class StringUtilsTest {
+ @Test
+ public void testDeCamelCase() {
+ testDeCamelCase("RedGreenBlue", "Red Green Blue");
+ testDeCamelCase("redGreenBlue", "Red Green Blue");
+ testDeCamelCase("Red Green Blue", "Red Green Blue");
+ testDeCamelCase("red green blue", "Red Green Blue");
+ testDeCamelCase("RHQServer", "RHQ Server");
+ testDeCamelCase("Blink182", "Blink 182");
+ testDeCamelCase("SimonAndGarfunkel", "Simon and Garfunkel");
+ }
+
+ private void testDeCamelCase(String input, String expectedResult) {
+ String result = StringUtils.deCamelCase(input);
+ assertEquals(result, expectedResult, "For input \"" + input + "\": ");
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
index e342b11..bb39f2d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
@@ -47,6 +47,7 @@ import org.rhq.enterprise.gui.coregui.client.report.ReportTopView;
import org.rhq.enterprise.gui.coregui.client.report.tag.TaggedView;
import org.rhq.enterprise.gui.coregui.client.util.ErrorHandler;
import org.rhq.enterprise.gui.coregui.client.util.WidgetUtility;
+import org.rhq.enterprise.gui.coregui.client.util.message.MessageBar;
import org.rhq.enterprise.gui.coregui.client.util.message.MessageCenter;
import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
@@ -61,6 +62,8 @@ public class CoreGUI implements EntryPoint, ValueChangeHandler<String> {
private static ErrorHandler errorHandler = new ErrorHandler();
+ private static MessageBar messageBar;
+
private static BreadcrumbTrailPane breadCrumbTrailPane;
private static MessageCenter messageCenter;
@@ -130,6 +133,8 @@ public class CoreGUI implements EntryPoint, ValueChangeHandler<String> {
MenuBarView menuBarView = new MenuBarView("TopMenu");
menuBarView.setWidth("100%");
+ messageBar = new MessageBar();
+
breadCrumbTrailPane = new BreadcrumbTrailPane();
Canvas canvas = new Canvas(CONTENT_CANVAS_ID);
@@ -139,9 +144,11 @@ public class CoreGUI implements EntryPoint, ValueChangeHandler<String> {
rootCanvas = new RootCanvas();
rootCanvas.setOverflow(Overflow.HIDDEN);
rootCanvas.addMember(menuBarView);
+
+ rootCanvas.addMember(messageBar);
rootCanvas.addMember(breadCrumbTrailPane);
rootCanvas.addMember(canvas);
- rootCanvas.addMember(new Footer("CoreFooter"));
+ rootCanvas.addMember(new Footer());
rootCanvas.draw();
History.addValueChangeHandler(this);
@@ -267,8 +274,8 @@ public class CoreGUI implements EntryPoint, ValueChangeHandler<String> {
}
private class RootCanvas extends VLayout implements BookmarkableView {
- ViewId currentViewId;
- Canvas currentCanvas;
+ private ViewId currentViewId;
+ private Canvas currentCanvas;
private RootCanvas() {
setWidth100();
@@ -280,14 +287,20 @@ public class CoreGUI implements EntryPoint, ValueChangeHandler<String> {
// default view
History.newItem(DEFAULT_VIEW_PATH);
} else {
- if (!viewPath.getCurrent().equals(currentViewId)) {
- currentViewId = viewPath.getCurrent();
+ messageBar.clearMessage();
- currentCanvas = createContent(viewPath.getCurrent().getPath());
- setContent(currentCanvas);
+ ViewId topLevelViewId = viewPath.getCurrent(); // e.g. Administration
+ if (!topLevelViewId.equals(this.currentViewId)) {
+ this.currentViewId = topLevelViewId;
+ this.currentCanvas = createContent(this.currentViewId.getPath());
+ setContent(this.currentCanvas);
}
- if (currentCanvas instanceof BookmarkableView) {
- ((BookmarkableView) currentCanvas).renderView(viewPath.next()); // e.g.
+
+ if (this.currentCanvas instanceof BookmarkableView) {
+ viewPath.next();
+ if (!viewPath.isEnd()) {
+ ((BookmarkableView) this.currentCanvas).renderView(viewPath);
+ }
}
refreshBreadCrumbTrail();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java
index 36514aa..d7121e3 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/Footer.java
@@ -40,9 +40,10 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableToolStrip;
* @author Joseph Marques
*/
public class Footer extends LocatableToolStrip {
+ private static final String LOCATOR_ID = "CoreFooter";
- public Footer(String locatorId) {
- super(locatorId);
+ public Footer() {
+ super(LOCATOR_ID);
setHeight(30);
setAlign(VerticalAlignment.CENTER);
// setPadding(5);
@@ -55,7 +56,7 @@ public class Footer extends LocatableToolStrip {
super.onDraw();
final UserSessionState userSessionState = new UserSessionState("UserSessionState");
- final MessageCenterView recentMessage = new MessageCenterView(extendLocatorId("MessageCenter"));
+ final MessageCenterView recentMessage = new MessageCenterView(extendLocatorId(MessageCenterView.LOCATOR_ID));
recentMessage.setWidth("*");
final FavoritesButton favoritesButton = new FavoritesButton(extendLocatorId("Favorites"));
final AlertsMessage alertsMessage = new AlertsMessage(extendLocatorId("Alerts"));
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
index 432cd2b..544ded9 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
@@ -65,6 +65,7 @@ import com.smartgwt.client.widgets.form.fields.events.ChangeEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangeHandler;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
+import com.smartgwt.client.widgets.form.validator.CustomValidator;
import com.smartgwt.client.widgets.form.validator.FloatRangeValidator;
import com.smartgwt.client.widgets.form.validator.IntegerRangeValidator;
import com.smartgwt.client.widgets.form.validator.RegExpValidator;
@@ -136,7 +137,6 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
* @author Ian Springer
*/
public class ConfigurationEditor extends LocatableVLayout {
-
private ConfigurationGWTServiceAsync configurationService = GWTServiceLookup.getConfigurationService();
private TabSet tabSet;
@@ -854,7 +854,7 @@ public class ConfigurationEditor extends LocatableVLayout {
valueItem.setRequired(propertyDefinition.isRequired());
- List<Validator> validators = buildValidators(propertyDefinition, valueItem);
+ List<Validator> validators = buildValidators(propertyDefinition, property);
valueItem.setValidators(validators.toArray(new Validator[validators.size()]));
/*
@@ -879,6 +879,7 @@ public class ConfigurationEditor extends LocatableVLayout {
finalValueItem.addChangedHandler(new ChangedHandler() {
public void onChanged(ChangedEvent changedEvent) {
boolean wasValidBefore = ConfigurationEditor.this.invalidPropertyNames.isEmpty();
+ propertySimple.setErrorMessage(null);
if (changedEvent.getItem().validate()) {
ConfigurationEditor.this.invalidPropertyNames.remove(propertySimple.getName());
propertySimple.setValue(changedEvent.getValue());
@@ -888,7 +889,7 @@ public class ConfigurationEditor extends LocatableVLayout {
boolean isValidNow = ConfigurationEditor.this.invalidPropertyNames.isEmpty();
if (isValidNow != wasValidBefore) {
for (ValidationStateChangeListener validationStateChangeListener : ConfigurationEditor.this.validationStateChangeListeners) {
- validationStateChangeListener.validateStateChanged(isValidNow);
+ validationStateChangeListener.validationStateChanged(isValidNow);
}
}
}
@@ -913,7 +914,7 @@ public class ConfigurationEditor extends LocatableVLayout {
return valueItem;
}
- private List<Validator> buildValidators(PropertyDefinitionSimple propertyDefinition, FormItem valueItem) {
+ private List<Validator> buildValidators(PropertyDefinitionSimple propertyDefinition, Property property) {
List<Validator> validators = new ArrayList<Validator>();
if (propertyDefinition.getConstraints() != null) {
Set<Constraint> constraints = propertyDefinition.getConstraints();
@@ -941,11 +942,16 @@ public class ConfigurationEditor extends LocatableVLayout {
validators.add(validator);
} else if (constraint instanceof RegexConstraint) {
RegExpValidator validator =
- new RegExpValidator("^" + ((RegexConstraint) constraint).getDetails() + "$");
+ new RegExpValidator("^" + constraint.getDetails() + "$");
validators.add(validator);
}
}
}
+ if (property.getErrorMessage() != null) {
+ this.invalidPropertyNames.add(property.getName());
+ PluginReportedErrorValidator validator = new PluginReportedErrorValidator(property);
+ validators.add(validator);
+ }
return validators;
}
@@ -1043,4 +1049,22 @@ public class ConfigurationEditor extends LocatableVLayout {
return new Integer(o1.getOrder()).compareTo(o2.getOrder());
}
}
+
+ private class PluginReportedErrorValidator extends CustomValidator {
+ private Property property;
+
+ public PluginReportedErrorValidator(Property property) {
+ this.property = property;
+ }
+
+ @Override
+ protected boolean condition(Object value) {
+ String errorMessage = this.property.getErrorMessage();
+ boolean valid = (errorMessage != null);
+ if (!valid) {
+ setErrorMessage(errorMessage);
+ }
+ return valid;
+ }
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ValidationStateChangeListener.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ValidationStateChangeListener.java
index d8f7a85..154c731 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ValidationStateChangeListener.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ValidationStateChangeListener.java
@@ -23,5 +23,5 @@ package org.rhq.enterprise.gui.coregui.client.components.configuration;
* @author Ian Springer
*/
public interface ValidationStateChangeListener {
- void validateStateChanged(boolean isValid);
+ void validationStateChanged(boolean isValid);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/wizard/AbstractWizard.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/wizard/AbstractWizard.java
index 9c8e513..57d29b5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/wizard/AbstractWizard.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/wizard/AbstractWizard.java
@@ -18,15 +18,13 @@
*/
package org.rhq.enterprise.gui.coregui.client.components.wizard;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.smartgwt.client.widgets.IButton;
public abstract class AbstractWizard implements Wizard {
-
- private ArrayList<WizardStep> steps;
+ private List<WizardStep> steps;
private WizardView view;
private String windowTitle = "";
private String title = "";
@@ -63,7 +61,7 @@ public abstract class AbstractWizard implements Wizard {
return steps;
}
- public void setSteps(ArrayList<WizardStep> steps) {
+ public void setSteps(List<WizardStep> steps) {
this.steps = steps;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/wizard/GroupCreateWizard.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/wizard/GroupCreateWizard.java
index fbbf71e..1008b83 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/wizard/GroupCreateWizard.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/wizard/GroupCreateWizard.java
@@ -30,18 +30,21 @@ import com.smartgwt.client.widgets.IButton;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.LinkManager;
import org.rhq.enterprise.gui.coregui.client.components.wizard.AbstractWizard;
import org.rhq.enterprise.gui.coregui.client.components.wizard.WizardStep;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupListView;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
+import org.rhq.enterprise.gui.coregui.client.util.message.TransientMessage;
/**
+ * A wizard for creating a new Resource group.
+ *
* @author Greg Hinkle
*/
public class GroupCreateWizard extends AbstractWizard {
-
private ResourceGroupListView resourceGroupListView;
private GroupCreateStep createStep;
@@ -50,7 +53,7 @@ public class GroupCreateWizard extends AbstractWizard {
public GroupCreateWizard(ResourceGroupListView resourceGroupListView) {
this.resourceGroupListView = resourceGroupListView;
- ArrayList<WizardStep> steps = new ArrayList<WizardStep>();
+ List<WizardStep> steps = new ArrayList<WizardStep>();
steps.add(createStep = new GroupCreateStep());
steps.add(memberStep = new GroupMembersStep(this));
@@ -84,13 +87,18 @@ public class GroupCreateWizard extends AbstractWizard {
groupService.createResourceGroup(createStep.getGroup(), memberStep.getSelectedResourceIds(),
new AsyncCallback<ResourceGroup>() {
public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to create resource group", caught);
+ CoreGUI.getErrorHandler().handleError("Failed to create Resource group.", caught);
}
public void onSuccess(ResourceGroup result) {
+ String groupUrl = LinkManager.getResourceGroupLink(result.getId());
CoreGUI.getMessageCenter().notify(
- new Message("Saved new group " + result.getName(), Message.Severity.Info));
-
+ new TransientMessage("Resource group created. [<a href='" + groupUrl + "'>View Group</a>]",
+ Message.Severity.Info));
+ CoreGUI.getMessageCenter().notify(
+ new Message("Created new " + result.getGroupCategory().name().toLowerCase() + " Resource group '"
+ + result.getName() + "' with " + memberStep.getSelectedResourceIds().length + " members.",
+ Message.Severity.Info));
resourceGroupListView.refresh();
}
});
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
index 7964a74..9843339 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java
@@ -34,18 +34,19 @@ import org.rhq.enterprise.gui.coregui.client.components.configuration.Configurat
import org.rhq.enterprise.gui.coregui.client.components.configuration.ValidationStateChangeListener;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
-import org.rhq.enterprise.gui.coregui.client.util.message.MessageBar;
+import org.rhq.enterprise.gui.coregui.client.util.message.MessageCenter;
+import org.rhq.enterprise.gui.coregui.client.util.message.TransientMessage;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
* @author Greg Hinkle
+ * @author Ian Springer
*/
public class ResourceConfigurationEditView extends LocatableVLayout implements ValidationStateChangeListener {
private Resource resource;
private ConfigurationEditor editor;
private IButton saveButton;
- private MessageBar messageBar;
public ResourceConfigurationEditView(String locatorId, Resource resource) {
super(locatorId);
@@ -74,14 +75,11 @@ public class ResourceConfigurationEditView extends LocatableVLayout implements V
this.saveButton.disable();
toolStrip.addMember(saveButton);
- this.messageBar = new MessageBar();
-
editor = new ConfigurationEditor(this.getLocatorId(), resource.getId(), resource.getResourceType().getId());
editor.setOverflow(Overflow.AUTO);
editor.addValidationStateChangeListener(this);
addMember(toolStrip);
- addMember(this.messageBar);
addMember(editor);
}
@@ -91,12 +89,12 @@ public class ResourceConfigurationEditView extends LocatableVLayout implements V
GWTServiceLookup.getConfigurationService().updateResourceConfiguration(resource.getId(), updatedConfiguration,
new AsyncCallback<ResourceConfigurationUpdate>() {
public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to update configuration", caught);
+ CoreGUI.getErrorHandler().handleError("Failed to update configuration.", caught);
}
public void onSuccess(ResourceConfigurationUpdate result) {
CoreGUI.getMessageCenter().notify(
- new Message("Configuration updated for resource [" + resource.getName() + "]",
+ new Message("Configuration updated for Resource [" + resource.getName() + "].",
Message.Severity.Info));
}
@@ -104,14 +102,16 @@ public class ResourceConfigurationEditView extends LocatableVLayout implements V
}
@Override
- public void validateStateChanged(boolean isValid) {
+ public void validationStateChanged(boolean isValid) {
+ MessageCenter messageCenter = CoreGUI.getMessageCenter();
+ Message message;
if (isValid) {
this.saveButton.enable();
- this.messageBar.hide();
+ message = new TransientMessage("All configuration properties now have valid values, so the configuration can now be saved.", Message.Severity.Info);
} else {
this.saveButton.disable();
- Message message = new Message("One or more properties have invalid values. The values must be fixed before the configuration can be saved.", Message.Severity.Error);
- this.messageBar.setMessage(message);
+ message = new TransientMessage("One or more configuration properties have invalid values. The values must be corrected before the configuration can be saved.", Message.Severity.Error, true);
}
+ messageCenter.notify(message);
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
index 357255a..d179046 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java
@@ -33,19 +33,19 @@ import org.rhq.enterprise.gui.coregui.client.components.configuration.Configurat
import org.rhq.enterprise.gui.coregui.client.components.configuration.ValidationStateChangeListener;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
-import org.rhq.enterprise.gui.coregui.client.util.message.MessageBar;
+import org.rhq.enterprise.gui.coregui.client.util.message.MessageCenter;
+import org.rhq.enterprise.gui.coregui.client.util.message.TransientMessage;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/**
* @author Greg Hinkle
+ * @author Ian Springer
*/
public class PluginConfigurationEditView extends LocatableVLayout implements ValidationStateChangeListener {
-
private Resource resource;
private ConfigurationEditor editor;
private LocatableIButton saveButton;
- private MessageBar messageBar;
public PluginConfigurationEditView(String locatorId, Resource resource) {
super(locatorId);
@@ -75,15 +75,12 @@ public class PluginConfigurationEditView extends LocatableVLayout implements Val
this.saveButton.disable();
toolStrip.addMember(saveButton);
- this.messageBar = new MessageBar();
-
editor = new ConfigurationEditor(this.getLocatorId(), resource.getId(), resource.getResourceType().getId(),
ConfigurationEditor.ConfigType.plugin);
editor.setOverflow(Overflow.AUTO);
editor.addValidationStateChangeListener(this);
addMember(toolStrip);
- addMember(this.messageBar);
addMember(editor);
}
@@ -103,18 +100,19 @@ public class PluginConfigurationEditView extends LocatableVLayout implements Val
}
});
-
}
@Override
- public void validateStateChanged(boolean isValid) {
+ public void validationStateChanged(boolean isValid) {
+ MessageCenter messageCenter = CoreGUI.getMessageCenter();
+ Message message;
if (isValid) {
this.saveButton.enable();
- this.messageBar.hide();
+ message = new TransientMessage("All connection properties now have valid values, so the configuration can now be saved.", Message.Severity.Info);
} else {
this.saveButton.disable();
- Message message = new Message("One or more properties have invalid values. The values must be fixed before the configuration can be saved.", Message.Severity.Error);
- this.messageBar.setMessage(message);
+ message = new TransientMessage("One or more connection properties have invalid values. The values must be corrected before the configuration can be saved.", Message.Severity.Error, true);
}
+ messageCenter.notify(message);
}
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
index 905b0c7..97cc7ab 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java
@@ -23,8 +23,8 @@ import java.util.Date;
/**
* @author Greg Hinkle
*/
+@SuppressWarnings({"UnnecessarySemicolon"})
public class Message {
-
protected String title;
protected String detail;
protected Date fired = new Date();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageBar.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageBar.java
index e025ab1..b03499f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageBar.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageBar.java
@@ -22,52 +22,114 @@ package org.rhq.enterprise.gui.coregui.client.util.message;
import java.util.HashMap;
import java.util.Map;
+import com.google.gwt.user.client.Timer;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.Label;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableHLayout;
+
/**
* A bar for displaying a message at the top of a page - the equivalent of the JSF h:messages component.
+ * The message will be displayed for 30 seconds and then will be automatically cleared.
*
* @author Ian Springer
*/
-public class MessageBar extends Label {
- public static final Map<Message.Severity, String> SEVERITY_TO_STYLE_NAME_MAP = new HashMap();
+public class MessageBar extends LocatableHLayout implements MessageCenter.MessageListener {
+ private static final String LOCATOR_ID = "MessageBar";
+ private static final int AUTO_HIDE_DELAY_MILLIS = 30000; // 30 seconds
+
+ private static final Map<Message.Severity, String> SEVERITY_TO_STYLE_NAME_MAP =
+ new HashMap<Message.Severity, String>();
static {
SEVERITY_TO_STYLE_NAME_MAP.put(Message.Severity.Info, "InfoBlock");
SEVERITY_TO_STYLE_NAME_MAP.put(Message.Severity.Warning, "WarnBlock");
SEVERITY_TO_STYLE_NAME_MAP.put(Message.Severity.Error, "ErrorBlock");
}
+ private static final Map<Message.Severity, String> SEVERITY_TO_ICON_MAP =
+ new HashMap<Message.Severity, String>();
+ static {
+ SEVERITY_TO_ICON_MAP.put(Message.Severity.Info, "info/icn_info_blue.png");
+ SEVERITY_TO_ICON_MAP.put(Message.Severity.Warning, "info/icn_info_orange.png");
+ SEVERITY_TO_ICON_MAP.put(Message.Severity.Error, "info/icn_info_red.png");
+ }
+
+ private Label label;
+
+ public MessageBar() {
+ super(LOCATOR_ID);
+
+ setOverflow(Overflow.VISIBLE);
+ }
+
@Override
protected void onDraw() {
super.onDraw();
setWidth100();
setAutoHeight();
+ setHeight(40);
- hide();
+ setAlign(Alignment.CENTER);
+
+ CoreGUI.getMessageCenter().addMessageListener(this);
}
- public void setMessage(Message message) {
+ @Override
+ public void onMessage(Message message) {
+ if (message instanceof TransientMessage) {
+ TransientMessage transientMessage = (TransientMessage)message;
+
+ // First clear any previous message.
+ clearMessage();
+
+ this.label = createLabel(transientMessage);
+ addMember(this.label);
+ markForRedraw();
- String contents;
- if (message != null) {
- contents = message.getTitle();
- if (message.getDetail() != null) {
- contents += ": " + message.getDetail();
+ // Auto-clear the message after 30 seconds unless it's been designated as sticky.
+ if (!transientMessage.isSticky()) {
+ Timer hideTimer = new Timer() {
+ @Override
+ public void run() {
+ clearMessage();
+ }
+ };
+ hideTimer.schedule(AUTO_HIDE_DELAY_MILLIS);
}
- } else {
- contents = null;
}
- setContents(contents);
- if (contents != null) {
- String styleName = SEVERITY_TO_STYLE_NAME_MAP.get(message.getSeverity());
- setStyleName(styleName);
+ }
+
+ public void clearMessage() {
+ if (this.label != null) {
+ this.label.destroy();
+ removeMember(this.label);
+ markForRedraw();
}
- markForRedraw();
- if (contents != null) {
- show();
- } else {
- hide();
+ }
+
+ private Label createLabel(Message message) {
+ Label label = new Label();
+
+ String contents = message.getTitle();
+ if (message.getDetail() != null) {
+ contents += ": " + message.getDetail();
}
+ label.setContents(contents);
+
+ String styleName = (contents != null) ? SEVERITY_TO_STYLE_NAME_MAP.get(message.getSeverity()) : null;
+ label.setStyleName(styleName);
+
+ label.setAutoHeight();
+ label.setHeight(35);
+ label.setAutoWidth();
+ label.setWidth("75%");
+
+ String icon = (contents != null) ? SEVERITY_TO_ICON_MAP.get(message.getSeverity()) : null;
+ label.setIcon(icon);
+
+ return label;
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java
index afce657..a3c29dd 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenter.java
@@ -20,15 +20,14 @@ package org.rhq.enterprise.gui.coregui.client.util.message;
import java.util.ArrayList;
import java.util.LinkedList;
+import java.util.List;
/**
* @author Greg Hinkle
*/
public class MessageCenter {
-
private LinkedList<Message> messages = new LinkedList<Message>();
-
- private ArrayList<MessageListener> listeners = new ArrayList<MessageListener>();
+ private List<MessageListener> listeners = new ArrayList<MessageListener>();
private static final int MAX_MESSAGES = 100;
@@ -46,7 +45,7 @@ public class MessageCenter {
this.listeners.add(listener);
}
- public LinkedList<Message> getMessages() {
+ public List<Message> getMessages() {
return messages;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
index 7b6d850..5d81646 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/MessageCenterView.java
@@ -18,7 +18,7 @@
*/
package org.rhq.enterprise.gui.coregui.client.util.message;
-import java.util.LinkedList;
+import java.util.List;
import com.google.gwt.user.client.Timer;
import com.smartgwt.client.types.Alignment;
@@ -53,6 +53,7 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableWindow;
* @author Greg Hinkle
*/
public class MessageCenterView extends LocatableHLayout implements MessageCenter.MessageListener {
+ public static final String LOCATOR_ID = "MessageCenter";
public MessageCenterView(String locatorId) {
super(locatorId, 5);
@@ -78,16 +79,16 @@ public class MessageCenterView extends LocatableHLayout implements MessageCenter
recentEventsButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent clickEvent) {
- LinkedList<Message> messages = CoreGUI.getMessageCenter().getMessages();
+ List<Message> messages = CoreGUI.getMessageCenter().getMessages();
if (messages.isEmpty()) {
- recentEventsMenu.setItems(new MenuItem("No recent messages"));
+ recentEventsMenu.setItems(new MenuItem("No recent messages."));
} else {
MenuItem[] items = new MenuItem[messages.size()];
- int i = 0;
- for (final Message message : messages) {
+ for (int i = 0, messagesSize = messages.size(); i < messagesSize; i++) {
+ final Message message = messages.get(i);
MenuItem messageItem = new MenuItem(message.title, getSeverityIcon(message.severity));
- items[i++] = messageItem;
+ items[i] = messageItem;
messageItem.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler() {
public void onClick(MenuItemClickEvent event) {
@@ -156,38 +157,40 @@ public class MessageCenterView extends LocatableHLayout implements MessageCenter
}
public void onMessage(final Message message) {
- final Label label = new Label(message.title);
- label.setMargin(5);
- label.setAutoFit(true);
- label.setHeight(25);
- label.setWrap(false);
+ if (!(message instanceof TransientMessage)) {
+ final Label label = new Label(message.title);
+ label.setMargin(5);
+ label.setAutoFit(true);
+ label.setHeight(25);
+ label.setWrap(false);
- String iconSrc = getSeverityIcon(message.severity);
+ String iconSrc = getSeverityIcon(message.severity);
- label.setIcon(iconSrc);
+ label.setIcon(iconSrc);
- label.setTooltip(message.detail);
+ label.setTooltip(message.detail);
- label.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent clickEvent) {
- showDetails(message);
- }
- });
-
- addMember(label, 1);
- redraw();
-
- Timer hideTimer = new Timer() {
- @Override
- public void run() {
- label.animateHide(AnimationEffect.FADE, new AnimationCallback() {
- public void execute(boolean b) {
- label.destroy();
- }
- });
- }
- };
- hideTimer.schedule(10000);
+ label.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
+ showDetails(message);
+ }
+ });
+
+ addMember(label, 1);
+ redraw();
+
+ Timer hideTimer = new Timer() {
+ @Override
+ public void run() {
+ label.animateHide(AnimationEffect.FADE, new AnimationCallback() {
+ public void execute(boolean b) {
+ label.destroy();
+ }
+ });
+ }
+ };
+ hideTimer.schedule(10000);
+ }
}
private String getSeverityIcon(Message.Severity severity) {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/TransientMessage.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/TransientMessage.java
new file mode 100644
index 0000000..318c4a5
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/TransientMessage.java
@@ -0,0 +1,48 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * 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.util.message;
+
+/**
+ * @author Ian Springer
+ */
+public class TransientMessage extends Message {
+ private boolean sticky;
+
+ public TransientMessage(String title, Severity severity) {
+ super(title, severity);
+ }
+
+ public TransientMessage(String title, String detail, Severity severity) {
+ super(title, detail, severity);
+ }
+
+ public TransientMessage(String title, Severity severity, boolean sticky) {
+ this(title, null, severity, sticky);
+ }
+
+ public TransientMessage(String title, String detail, Severity severity, boolean sticky) {
+ super(title, detail, severity);
+ this.sticky = sticky;
+ }
+
+ public boolean isSticky() {
+ return this.sticky;
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
index c5d324e..85d1b83 100644
--- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
+++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
@@ -361,29 +361,29 @@ a:hover {
}
.InfoBlock,.ConfirmationBlock,.WarnBlock,.ErrorBlock,.FatalBlock {
- padding: 4px;
+ /*padding: 4px;*/
border-width: 1px;
- border-top-style: solid;
- font-size: 10px;
+ border-style: solid;
+ /*font-size: 10px;*/
color: #000000;
}
.InfoBlock,.ConfirmationBlock {
background-color: #BFF1B5; /* light green */
- border-top-color: #00AC3D; /* medium green */
+ border-color: #00AC3D; /* medium green */
}
.WarnBlock {
background-color: #FFFD99; /* light yellow */
- border-top-color: #FF9C15; /* medium orange */
+ border-color: #FF9C15; /* medium orange */
}
.ErrorBlock {
background-color: #FF9999; /* light red */
- border-top-color: #EE4444; /* medium red */
+ border-color: #EE4444; /* medium red */
}
.FatalBlock {
background-color: #FF6666; /* slightly darker light red */
- border-top-color: #EE1111; /* slightly darker medium red */
+ border-color: #EE1111; /* slightly darker medium red */
}