modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java | 12 modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java | 12 modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 20 modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java | 4 modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java | 12 modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java | 3 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml | 13 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java | 22 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java | 2 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java | 12 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java | 19 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java | 202 ++++ modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java | 203 ++++ modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java | 3 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java | 429 ++++++---- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java | 21 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ResourceConfigurationEditView.java | 2 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/inventory/PluginConfigurationEditView.java | 2 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java | 4 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java | 37 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java | 41 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/message/Message.java | 45 - modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java | 30 modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css | 6 modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java | 4 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java | 2 modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java | 142 +-- modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml | 41 modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml | 47 + modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java | 83 - modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml | 12 modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml | 22 modules/enterprise/server/plugins/alert-subject/pom.xml | 21 modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsBackingBean.java | 84 - modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml | 14 modules/enterprise/server/plugins/alert-subject/src/main/resources/subjects.xhtml | 22 36 files changed, 1073 insertions(+), 577 deletions(-)
New commits: commit 065319e2048376d93509e31dd526789b26947b4f Merge: 98a4d17... 297cc73... Author: Lukas Krejci lkrejci@redhat.com Date: Tue Oct 5 12:49:38 2010 +0200
Merge branch 'master' into resource-upgrade
commit 98a4d17665d0fed83e0fd2c28770545178b00150 Author: Lukas Krejci lkrejci@redhat.com Date: Tue Oct 5 12:48:12 2010 +0200
making the getResourcesWithType(ResourceType, Set<Resource>) private again.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java index c5004dd..351f751 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java @@ -1668,7 +1668,7 @@ public class InventoryManager extends AgentService implements ContainerService, return getResourcesWithType(serverType, this.platform.getChildResources()); }
- public Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) { + private Set<Resource> getResourcesWithType(ResourceType serverType, Set<Resource> resources) { Set<Resource> servers = new HashSet<Resource>();
if (resources == null) {
commit 297cc733d3b5567a444131892c4766d6852fa80e Author: Joseph Marques joseph@redhat.com Date: Tue Oct 5 01:22:58 2010 -0400
add todos for future infrastructure work
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java index a779117..d0760d2 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java @@ -139,9 +139,15 @@ public class GWTServiceLookup {
public static class SessionRpcRequestBuilder extends RpcRequestBuilder {
+ private static int RPC_TIMEOUT = 10000; + @Override - protected void doFinish(RequestBuilder rb) { - super.doFinish(rb); + protected RequestBuilder doCreate(String serviceEntryPoint) { + RequestBuilder rb = super.doCreate(serviceEntryPoint); + + // TODO: alter callback handlers to capture timeout failure and retry (at least once) + // to add resilience to gwt service calls + rb.setTimeoutMillis(RPC_TIMEOUT);
// TODO Don't use the expensive determineName except in dev mode rb.setCallback(new MonitoringRequestCallback(determineName(), rb.getCallback())); @@ -155,6 +161,8 @@ public class GWTServiceLookup { .error("SessionRpcRequestBuilder constructed without a value for " + UserSessionManager.SESSION_NAME); } + + return rb; }
public String determineName() { diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java index c9da68a..364140f 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java @@ -19,6 +19,7 @@ package org.rhq.enterprise.gui.coregui.server.gwt;
import java.io.IOException; +import java.util.Enumeration;
import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -49,6 +50,9 @@ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + if (Log.isTraceEnabled()) { + printHeaders(req); + } String sid = req.getHeader(UserSessionManager.SESSION_NAME); if (sid != null) { SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager(); @@ -62,8 +66,22 @@ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet { Log.error("Failed to validate request: sessionId missing, requestURL=" + req.getRequestURL()); }
+ // TODO: only execute this if the session lookup was successful, otherwise fail in some deterministic fashion + // alter callback handlers to capture expected failure and retry (at least once) + // to add resilience to gwt service calls long id = HibernatePerformanceMonitor.get().start(); super.service(req, resp); HibernatePerformanceMonitor.get().stop(id, "GWT Service Request"); } + + @SuppressWarnings("unchecked") + private void printHeaders(HttpServletRequest req) { + // TODO: figure out why SESSION_NAME header and other GWT-specific headers are missing occasionally + // seems to only happen on polling for recent alerts when there is no user activity for a few minutes + Enumeration<String> headerNames = req.getHeaderNames(); + Log.trace(req.getRequestURL().toString()); + while (headerNames.hasMoreElements()) { + Log.trace(" " + headerNames.nextElement()); + } + } }
commit 83c0317378f20d3a9aa1bf92bcf645a771a41e84 Author: Joseph Marques joseph@redhat.com Date: Mon Oct 4 23:29:01 2010 -0400
fix z-index so log_DivLogger can be used if developers so choose
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css index 85d1b83..54cc3a9 100644 --- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css +++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css @@ -317,11 +317,9 @@ a:hover { -moz-box-sizing: border-box; overflow: hidden; cursor: auto; - z-index: 9999999; }
.gwtMenu, .gwt-MenuBarPopup, .gwt-MenuPopup { - z-index: 9999999; background-color: white; }
@@ -387,3 +385,7 @@ a:hover { background-color: #FF6666; /* slightly darker light red */ border-color: #EE1111; /* slightly darker medium red */ } + +.log-panel { + z-index: 9999999 !important; +}
commit 84ae15fae55dbaf217217cb4bb1c0edc58c4c907 Author: Joseph Marques joseph@redhat.com Date: Mon Oct 4 17:41:07 2010 -0400
better logging around request-response workflow and user session management
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java index ecbd719..65faa6d 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/UserSessionManager.java @@ -56,7 +56,7 @@ import org.rhq.enterprise.gui.coregui.client.util.preferences.UserPreferences; public class UserSessionManager {
private static int SESSION_TIMEOUT = 29 * 60 * 1000; // 29 mins, just shorter than the 30-min web session timeout - private static int LOGOUT_DELAY = 15 * 1000; // wait 15 seconds for in-flight requests to complete before logout + private static int LOGOUT_DELAY = 5 * 1000; // wait 5 seconds for in-flight requests to complete before logout
public static final String SESSION_NAME = "RHQ_Sesssion"; private static Subject sessionSubject; @@ -88,7 +88,7 @@ public class UserSessionManager { try { b.setCallback(new RequestCallback() { public void onResponseReceived(final Request request, final Response response) { - com.allen_sauer.gwt.log.client.Log.info("response text = " + response.getText()); + Log.info("response text = " + response.getText()); String sessionIdString = response.getText(); if (sessionIdString != null && sessionIdString.length() > 0) {
@@ -96,20 +96,20 @@ public class UserSessionManager { final int subjectId = Integer.parseInt(parts[0]); final String sessionId = parts[1]; // not null final long lastAccess = Long.parseLong(parts[2]); - com.allen_sauer.gwt.log.client.Log.info("sessionAccess-subjectId: " + subjectId); - com.allen_sauer.gwt.log.client.Log.info("sessionAccess-sessionId: " + sessionId); - com.allen_sauer.gwt.log.client.Log.info("sessionAccess-lastAccess: " + lastAccess); + Log.info("sessionAccess-subjectId: " + subjectId); + Log.info("sessionAccess-sessionId: " + sessionId); + Log.info("sessionAccess-lastAccess: " + lastAccess);
String previousSessionId = getPreviousSessionId(); // may be null - com.allen_sauer.gwt.log.client.Log.info("sessionAccess-previousSessionId: " + previousSessionId); + Log.info("sessionAccess-previousSessionId: " + previousSessionId); if (previousSessionId == null || previousSessionId.equals(sessionId) == false) {
// persist sessionId if different from previously saved sessionId - com.allen_sauer.gwt.log.client.Log.info("sessionAccess-savingSessionId: " + sessionId); + Log.info("sessionAccess-savingSessionId: " + sessionId); saveSessionId(sessionId);
// new sessions get the full 29 minutes to expire - com.allen_sauer.gwt.log.client.Log.info("sessionAccess-schedulingSessionTimeout: " + SESSION_TIMEOUT); + Log.info("sessionAccess-schedulingSessionTimeout: " + SESSION_TIMEOUT); sessionTimer.schedule(SESSION_TIMEOUT); } else {
@@ -124,7 +124,7 @@ public class UserSessionManager { expiryMillis = SESSION_TIMEOUT; // guarantees maximum is 29 minutes }
- com.allen_sauer.gwt.log.client.Log.info("sessionAccess-reschedulingSessionTimeout: " + expiryMillis); + Log.info("sessionAccess-reschedulingSessionTimeout: " + expiryMillis); sessionTimer.schedule((int) expiryMillis); }
@@ -143,7 +143,7 @@ public class UserSessionManager { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError( "UserSessionManager: Failed to load user's subject", caught); - com.allen_sauer.gwt.log.client.Log.info("Failed to load user's subject"); + Log.info("Failed to load user's subject"); new LoginView().showLoginDialog(); }
@@ -260,10 +260,12 @@ public class UserSessionManager {
public static String getSessionId() { if (sessionSubject == null) { + Log.error("UserSessionManager: sessionSubject is null"); return null; } Integer sessionId = sessionSubject.getSessionId(); if (sessionId == null) { + Log.error("UserSessionManager: sessionId is null"); return null; } return sessionId.toString(); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java index 4a9c639..a779117 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/GWTServiceLookup.java @@ -18,6 +18,7 @@ */ package org.rhq.enterprise.gui.coregui.client.gwt;
+import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.user.client.rpc.RpcRequestBuilder; import com.google.gwt.user.client.rpc.ServiceDefTarget; @@ -139,11 +140,6 @@ public class GWTServiceLookup { public static class SessionRpcRequestBuilder extends RpcRequestBuilder {
@Override - protected void doSetRequestData(RequestBuilder rb, String data) { - super.doSetRequestData(rb, data); // TODO: Implement this method. - } - - @Override protected void doFinish(RequestBuilder rb) { super.doFinish(rb);
@@ -152,7 +148,12 @@ public class GWTServiceLookup {
String sessionId = UserSessionManager.getSessionId(); if (sessionId != null) { + Log.info("SessionRpcRequestBuilder is adding sessionId to request: " + sessionId); rb.setHeader(UserSessionManager.SESSION_NAME, sessionId); + } else { + Log + .error("SessionRpcRequestBuilder constructed without a value for " + + UserSessionManager.SESSION_NAME); } }
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java index ae1e85b..c9da68a 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AbstractGWTServiceImpl.java @@ -24,6 +24,7 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
+import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.rhq.core.domain.auth.Subject; @@ -34,9 +35,12 @@ import org.rhq.enterprise.server.util.LookupUtil;
/** * @author Greg Hinkle + * @author Joseph Marques */ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet {
+ private static final long serialVersionUID = 1L; + private ThreadLocal<Subject> sessionSubject = new ThreadLocal<Subject>();
protected Subject getSessionSubject() { @@ -46,20 +50,20 @@ public abstract class AbstractGWTServiceImpl extends RemoteServiceServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String sid = req.getHeader(UserSessionManager.SESSION_NAME); - Subject subject = null; if (sid != null) { SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager(); try { - subject = subjectManager.getSubjectBySessionId(Integer.parseInt(sid)); + Subject subject = subjectManager.getSubjectBySessionId(Integer.parseInt(sid)); + sessionSubject.set(subject); } catch (Exception e) { - throw new RuntimeException("Failed to validate session", e); + Log.error("Failed to validate request: sessionId was '" + sid + "', requestURL=" + req.getRequestURL()); } + } else { + Log.error("Failed to validate request: sessionId missing, requestURL=" + req.getRequestURL()); } - sessionSubject.set(subject);
long id = HibernatePerformanceMonitor.get().start(); super.service(req, resp); HibernatePerformanceMonitor.get().stop(id, "GWT Service Request"); } - }
commit 34d44ee66ec927b1dbb1d96fc15de3250622e7e4 Author: Joseph Marques joseph@redhat.com Date: Mon Oct 4 14:07:42 2010 -0400
remove duplicate servlet definitions, alphabetize the rest
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml index c486f1d..ecfac0b 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml @@ -80,8 +80,11 @@ <servlet path="/AuthorizationGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.AuthorizationGWTServiceImpl"/> <servlet path="/AvailabilityGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.AvailabilityGWTServiceImpl"/> <servlet path="/BundleGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.BundleGWTServiceImpl"/> + <servlet path="/ClusterGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ClusterGWTServiceImpl"/> <servlet path="/ConfigurationGwtService" class="org.rhq.enterprise.gui.coregui.server.gwt.ConfigurationGWTServiceImpl"/> <servlet path="/ContentGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ContentGWTServiceImpl"/> + <servlet path="/DashboardGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.DashboardGWTServiceImpl"/> + <servlet path="/EventGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.EventGWTServiceImpl"/> <servlet path="/MeasurementDataGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.MeasurementDataGWTServiceImpl"/> <servlet path="/OperationGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.OperationGWTServiceImpl"/> <servlet path="/RemoteInstallGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.RemoteInstallGWTServiceImpl"/> @@ -95,11 +98,5 @@ <servlet path="/SubjectGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.SubjectGWTServiceImpl"/> <servlet path="/SystemGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.SystemGWTServiceImpl"/> <servlet path="/TagGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.TagGWTServiceImpl"/> - <servlet path="/RemoteInstallGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.RemoteInstallGWTServiceImpl"/> - <servlet path="/RepoGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.RepoGWTServiceImpl"/> - <servlet path="/ContentGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ContentGWTServiceImpl"/> - <servlet path="/DashboardGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.DashboardGWTServiceImpl"/> - <servlet path="/EventGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.EventGWTServiceImpl"/> - <servlet path="/ClusterGWTService" class="org.rhq.enterprise.gui.coregui.server.gwt.ClusterGWTServiceImpl"/>
-</module> \ No newline at end of file +</module>
commit 01bb66ff5713c644f2f7bb4d46763a0866276eb5 Author: Joseph Marques joseph@redhat.com Date: Mon Oct 4 14:03:50 2010 -0400
show as much detail in the message center as possible
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java index 34e343e..e62b908 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/create/BundleUploadDataStep.java @@ -204,8 +204,7 @@ public class BundleUploadDataStep extends AbstractWizardStep { uploadForm.addFormSubmitFailedHandler(new FormSubmitFailedHandler() { public void onFormSubmitFailed(FormSubmitFailedEvent event) { allFilesStatus.put(uploadForm.getName(), Boolean.FALSE); - CoreGUI.getMessageCenter().notify( - new Message("Failed to upload file", null, Message.Severity.Error)); + CoreGUI.getMessageCenter().notify(new Message("Failed to upload file", Message.Severity.Error)); } });
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java index 49bb67e..1b97a65 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java @@ -18,11 +18,14 @@ */ package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.ArrayList; + import org.rhq.enterprise.gui.coregui.client.CoreGUI; import org.rhq.enterprise.gui.coregui.client.util.message.Message;
/** * @author Greg Hinkle + * @author Joseph Marques */ public class ErrorHandler { public void handleError(String message) { @@ -30,7 +33,7 @@ public class ErrorHandler { }
public void handleError(String message, Throwable t) { - Message errorMessage = new Message(message, (t == null) ? null : t.toString(), Message.Severity.Fatal); + Message errorMessage = new Message(message, t, Message.Severity.Fatal); CoreGUI.getMessageCenter().notify(errorMessage);
if (t != null) { @@ -38,4 +41,40 @@ public class ErrorHandler { t.printStackTrace(); } } + + public static String getAllMessages(Throwable t) { + StringBuffer results = new StringBuffer(); + + if (t != null) { + String[] msgs = getAllMessagesArray(t); + results.append(msgs[0]); + + String indent = " "; + for (int i = 1; i < msgs.length; i++) { + results.append("\n").append(indent); + results.append(msgs[i]); + indent = indent + " "; + } + } else { + results.append(">> exception was null <<"); + } + + return results.toString(); + } + + public static String[] getAllMessagesArray(Throwable t) { + ArrayList<String> list = new ArrayList<String>(); + + if (t != null) { + list.add(t.getClass().getName() + ":" + t.getMessage()); + + while ((t.getCause() != null) && (t != t.getCause())) { + t = t.getCause(); + + list.add(t.getClass().getName() + ":" + t.getMessage()); + } + } + + return list.toArray(new String[list.size()]); + } } 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 3a0b464..a9e94c2 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 @@ -21,13 +21,14 @@ package org.rhq.enterprise.gui.coregui.client.util.message; import java.util.Date; import java.util.EnumSet;
+import org.rhq.enterprise.gui.coregui.client.util.ErrorHandler; + /** * A message to be displayed to the user in one or more places. * * @author Greg Hinkle * @author Ian Springer */ -@SuppressWarnings({"UnnecessarySemicolon"}) public class Message { protected String conciseMessage; protected String detailedMessage; @@ -36,21 +37,30 @@ public class Message { protected EnumSet<Option> options;
// TODO: Add Debug severity? - public enum Severity { Info, Warning, Error, Fatal }; - public enum Option { Transient, Sticky, BackgroundJobResult }; + public enum Severity { + Info, Warning, Error, Fatal + }; + + public enum Option { + Transient, Sticky, BackgroundJobResult + };
public Message(String conciseMessage) { - this(conciseMessage, (Severity)null); + this(conciseMessage, (Severity) null); }
public Message(String conciseMessage, Severity severity) { - this(conciseMessage, null, severity); + this(conciseMessage, (String) null, severity); }
public Message(String conciseMessage, String detailedMessage) { this(conciseMessage, detailedMessage, null); }
+ public Message(String conciseMessage, Throwable details) { + this(conciseMessage, details, null); + } + public Message(String conciseMessage, EnumSet<Option> options) { this(conciseMessage, null, options); } @@ -59,8 +69,16 @@ public class Message { this(conciseMessage, detailedMessage, severity, null); }
+ public Message(String conciseMessage, Throwable details, Severity severity) { + this(conciseMessage, details, severity, null); + } + public Message(String conciseMessage, Severity severity, EnumSet<Option> options) { - this(conciseMessage, null, severity, options); + this(conciseMessage, (String) null, severity, options); + } + + public Message(String conciseMessage, Throwable details, Severity severity, EnumSet<Option> options) { + this(conciseMessage, ErrorHandler.getAllMessages(details), severity, options); }
public Message(String conciseMessage, String detailedMessage, Severity severity, EnumSet<Option> options) { @@ -97,15 +115,14 @@ public class Message { public boolean isBackgroundJobResult() { return options.contains(Option.BackgroundJobResult); } - + @Override public String toString() { - return "Message{" + - "conciseMessage='" + this.conciseMessage + ''' + - ", detailedMessage='" + this.detailedMessage + ''' + - ", fired=" + this.fired + - ", severity=" + this.severity + - ", options=" + this.options + - '}'; + return "Message{" // + + "conciseMessage='" + this.conciseMessage + ''' // + + ", detailedMessage='" + this.detailedMessage + ''' // + + ", fired=" + this.fired // + + ", severity=" + this.severity // + + ", options=" + this.options + '}'; } }
commit 25ccc993e3a166cbad9e03bf609343cb3b744c5a Author: Ian Springer ian.springer@redhat.com Date: Mon Oct 4 21:30:38 2010 -0400
finish support for lists of maps in config editor
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 d9c3dd7..fc63830 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 @@ -147,12 +147,14 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout; */ @SuppressWarnings({"UnnecessarySemicolon"}) public class ConfigurationEditor extends LocatableVLayout { + private static final String RHQ_PROPERTY_ATTRIBUTE_NAME = "rhq:property"; + private ConfigurationGWTServiceAsync configurationService = GWTServiceLookup.getConfigurationService();
private TabSet tabSet; private LocatableToolStrip toolStrip;
- private ConfigurationDefinition definition; + private ConfigurationDefinition configurationDefinition; private Configuration configuration; private Configuration originalConfiguration;
@@ -169,7 +171,7 @@ public class ConfigurationEditor extends LocatableVLayout {
private boolean readOnly = false; private Set<String> invalidPropertyNames = new HashSet<String>(); - private Set<PropertyValueChangeListener> validationStateChangeListeners = + private Set<PropertyValueChangeListener> propertyValueChangeListeners = new HashSet<PropertyValueChangeListener>();
public static enum ConfigType { @@ -193,10 +195,11 @@ public class ConfigurationEditor extends LocatableVLayout { setOverflow(Overflow.AUTO); }
- public ConfigurationEditor(String locatorId, ConfigurationDefinition definition, Configuration configuration) { + public ConfigurationEditor(String locatorId, ConfigurationDefinition configurationDefinition, + Configuration configuration) { super(locatorId); this.configuration = configuration; - this.definition = definition; + this.configurationDefinition = configurationDefinition; }
public Configuration getConfiguration() { @@ -227,8 +230,8 @@ public class ConfigurationEditor extends LocatableVLayout { return this.valuesManager.hasErrors(); }
- public void addValidationStateChangeListener(PropertyValueChangeListener validationStateChangeListener) { - this.validationStateChangeListeners.add(validationStateChangeListener); + public void addPropertyValueChangeListener(PropertyValueChangeListener propertyValueChangeListener) { + this.propertyValueChangeListeners.add(propertyValueChangeListener); }
@Override @@ -240,7 +243,7 @@ public class ConfigurationEditor extends LocatableVLayout {
final long start = System.currentTimeMillis();
- if (definition == null || configuration == null) { + if (configurationDefinition == null || configuration == null) {
if (configType == ConfigType.resource) { configurationService.getResourceConfiguration(resourceId, new AsyncCallback<Configuration>() { @@ -260,8 +263,8 @@ public class ConfigurationEditor extends LocatableVLayout { new ResourceTypeRepository.TypesLoadedCallback() { public void onTypesLoaded(Map<Integer, ResourceType> types) { com.allen_sauer.gwt.log.client.Log.debug("ConfigDef retreived in: " + (System.currentTimeMillis() - start)); - definition = types.get(resourceTypeId).getResourceConfigurationDefinition(); - if (definition == null) { + configurationDefinition = types.get(resourceTypeId).getResourceConfigurationDefinition(); + if (configurationDefinition == null) { loadingLabel.hide(); showError("Configuration is not supported by this Resource."); } @@ -286,8 +289,8 @@ public class ConfigurationEditor extends LocatableVLayout { new ResourceTypeRepository.TypesLoadedCallback() { public void onTypesLoaded(Map<Integer, ResourceType> types) { com.allen_sauer.gwt.log.client.Log.debug("ConfigDef retreived in: " + (System.currentTimeMillis() - start)); - definition = types.get(resourceTypeId).getPluginConfigurationDefinition(); - if (definition == null) { + configurationDefinition = types.get(resourceTypeId).getPluginConfigurationDefinition(); + if (configurationDefinition == null) { showError("Connection settings are not supported by this Resource."); } reload(); @@ -300,7 +303,7 @@ public class ConfigurationEditor extends LocatableVLayout { }
public void reload() { - if (definition == null || configuration == null) { + if (configurationDefinition == null || configuration == null) { // Wait for both to load return; } @@ -309,16 +312,16 @@ public class ConfigurationEditor extends LocatableVLayout {
tabSet = new LocatableTabSet(getLocatorId());
- if (definition.getConfigurationFormat() == ConfigurationFormat.RAW - || definition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) { + if (configurationDefinition.getConfigurationFormat() == ConfigurationFormat.RAW + || configurationDefinition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) { com.allen_sauer.gwt.log.client.Log.info("Loading files view..."); Tab tab = new LocatableTab("Files", "Files"); tab.setPane(buildRawPane()); tabSet.addTab(tab); }
- if (definition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED - || definition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) { + if (configurationDefinition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED + || configurationDefinition.getConfigurationFormat() == ConfigurationFormat.STRUCTURED_AND_RAW) { com.allen_sauer.gwt.log.client.Log.info("Loading properties view..."); Tab tab = new LocatableTab("Properties", "Properties"); tab.setPane(buildStructuredPane()); @@ -391,7 +394,7 @@ public class ConfigurationEditor extends LocatableVLayout { protected VLayout buildStructuredPane() {
LocatableVLayout layout = new LocatableVLayout(extendLocatorId("Structured")); - List<PropertyGroupDefinition> definitions = definition.getGroupDefinitions(); + List<PropertyGroupDefinition> definitions = configurationDefinition.getGroupDefinitions();
final SectionStack sectionStack = new LocatableSectionStack(layout.extendLocatorId("Sections")); sectionStack.setVisibilityMode(VisibilityMode.MULTIPLE); @@ -400,7 +403,7 @@ public class ConfigurationEditor extends LocatableVLayout { sectionStack.setScrollSectionIntoView(true); sectionStack.setOverflow(Overflow.AUTO);
- if (definition.getNonGroupedProperties().size() > 0) { + if (configurationDefinition.getNonGroupedProperties().size() > 0) { sectionStack.addSection(buildGroupSection(layout.extendLocatorId("NoGroup"), null)); }
@@ -481,8 +484,8 @@ public class ConfigurationEditor extends LocatableVLayout { section.setExpanded(!group.isDefaultHidden()); }
- List<PropertyDefinition> propertyDefinitions = new ArrayList<PropertyDefinition>(((group == null) ? definition - .getNonGroupedProperties() : definition.getPropertiesInGroup(group.getName()))); + List<PropertyDefinition> propertyDefinitions = new ArrayList<PropertyDefinition>(((group == null) ? configurationDefinition + .getNonGroupedProperties() : configurationDefinition.getPropertiesInGroup(group.getName())));
DynamicForm form = buildPropertiesForm(locatorId + "_Props", propertyDefinitions, configuration);
@@ -748,6 +751,7 @@ public class ConfigurationEditor extends LocatableVLayout { PropertySimple prop = propertyMap.getSimple(propertyName); if (prop == null) { prop = new PropertySimple(propertyName, null); + propertyMap.put(prop); } String value = record.getAttribute("Value"); prop.setStringValue(value); @@ -778,14 +782,30 @@ public class ConfigurationEditor extends LocatableVLayout { summaryTable.setOverflow(Overflow.VISIBLE); summaryTable.setAutoFitData(Autofit.HORIZONTAL);
- ArrayList<ListGridField> fieldsList = new ArrayList<ListGridField>(); - ArrayList<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(memberPropertyDefinitionMap + summaryTable.addCellSavedHandler(new CellSavedHandler() { + public void onCellSaved(CellSavedEvent cellSavedEvent) { + Record record = cellSavedEvent.getRecord(); + PropertyMap propertyMap = (PropertyMap)record.getAttributeAsObject(RHQ_PROPERTY_ATTRIBUTE_NAME); + for (String memberPropertyName : memberPropertyDefinitionMap.getPropertyDefinitions().keySet()) { + PropertySimple memberProperty = propertyMap.getSimple(memberPropertyName); + if (memberProperty == null) { + memberProperty = new PropertySimple(memberPropertyName, null); + propertyMap.put(memberProperty); + } + String newValue = record.getAttribute(memberPropertyName); + memberProperty.setStringValue(newValue); + } + } + }); + + List<ListGridField> fieldsList = new ArrayList<ListGridField>(); + List<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(memberPropertyDefinitionMap .getPropertyDefinitions().values()); Collections.sort(definitions, new PropertyDefinitionComparator());
for (PropertyDefinition subDef : definitions) { if (subDef.isSummary()) { - ListGridField field = new ListGridField(subDef.getName(), subDef.getDisplayName()); + ListGridField field = new ListGridField(subDef.getName(), subDef.getDisplayName(), 90);
PropertyDefinitionSimple defSimple = (PropertyDefinitionSimple) subDef; if (defSimple.getType() == PropertySimpleType.INTEGER) { @@ -798,7 +818,7 @@ public class ConfigurationEditor extends LocatableVLayout { } }
- if (fieldsList.size() == 0) { + if (fieldsList.isEmpty()) { // An extra "feature of the config system". If no fields are labeled summary, all are considered summary. for (PropertyDefinition subDef : definitions) { ListGridField field = new ListGridField(subDef.getName(), subDef.getDisplayName()); @@ -809,7 +829,6 @@ public class ConfigurationEditor extends LocatableVLayout { } else if (defSimple.getType() == PropertySimpleType.FLOAT) { field.setType(ListGridFieldType.FLOAT); } - } }
@@ -823,10 +842,11 @@ public class ConfigurationEditor extends LocatableVLayout { editField.setCanHide(false); editField.addRecordClickHandler(new RecordClickHandler() { public void onRecordClick(RecordClickEvent recordClickEvent) { - com.allen_sauer.gwt.log.client.Log.info("You want to edit: " + recordClickEvent.getRecord()); + Log.info("You want to edit: " + recordClickEvent.getRecord()); + PropertyMap memberPropertyMap = (PropertyMap)recordClickEvent.getRecord().getAttributeAsObject( + RHQ_PROPERTY_ATTRIBUTE_NAME); displayMapEditor(locatorId + "_MapEdit", summaryTable, recordClickEvent.getRecord(), - memberPropertyDefinitionMap, propertyList, (PropertyMap) recordClickEvent.getRecord().getAttributeAsObject( - "_RHQ_PROPERTY")); + memberPropertyDefinitionMap, propertyList, memberPropertyMap); } }); fieldsList.add(editField); @@ -845,7 +865,7 @@ public class ConfigurationEditor extends LocatableVLayout {
removeField.addRecordClickHandler(new RecordClickHandler() { public void onRecordClick(final RecordClickEvent recordClickEvent) { - com.allen_sauer.gwt.log.client.Log.info("You want to delete: " + recordClickEvent.getRecordNum()); + Log.info("You want to delete: " + recordClickEvent.getRecordNum()); SC.confirm("Are you sure you want to delete this row?", new BooleanCallback() { public void execute(Boolean aBoolean) { if (aBoolean) { @@ -862,6 +882,7 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTable.setFields(fieldsList.toArray(new ListGridField[fieldsList.size()]));
+ // Now add rows containing the actual data (i.e. member property values). ListGridRecord[] rows = buildSummaryRecords(propertyList, definitions); summaryTable.setData(rows);
@@ -886,7 +907,7 @@ public class ConfigurationEditor extends LocatableVLayout { return item; }
- private ListGridRecord[] buildSummaryRecords(PropertyList propertyList, ArrayList<PropertyDefinition> definitions) { + private ListGridRecord[] buildSummaryRecords(PropertyList propertyList, List<PropertyDefinition> definitions) { ListGridRecord[] rows = new ListGridRecord[propertyList == null ? 0 : propertyList.getList().size()]; int i = 0; for (Property row : propertyList.getList()) { @@ -897,11 +918,11 @@ public class ConfigurationEditor extends LocatableVLayout { return rows; }
- private ListGridRecord buildSummaryRecord(List<PropertyDefinition> definitions, PropertyMap rowMap) { + private ListGridRecord buildSummaryRecord(List<PropertyDefinition> memberPropertyDefinitions, PropertyMap memberPropertyMap) { ListGridRecord record = new ListGridRecord(); - for (PropertyDefinition subDef : definitions) { + for (PropertyDefinition subDef : memberPropertyDefinitions) { PropertyDefinitionSimple subDefSimple = (PropertyDefinitionSimple) subDef; - PropertySimple propertySimple = ((PropertySimple) rowMap.get(subDefSimple.getName())); + PropertySimple propertySimple = ((PropertySimple) memberPropertyMap.get(subDefSimple.getName()));
if (propertySimple.getStringValue() != null) { record.setAttribute(subDefSimple.getName(), propertySimple.getStringValue()); @@ -930,13 +951,12 @@ public class ConfigurationEditor extends LocatableVLayout {
} } - record.setAttribute("_RHQ_PROPERTY", rowMap); + record.setAttribute(RHQ_PROPERTY_ATTRIBUTE_NAME, memberPropertyMap); return record; }
private FormItem buildSimpleField(final PropertyDefinitionSimple propertyDefinition, - final PropertySimple propertySimple - ) { + final PropertySimple propertySimple) { Log.debug("Building simple field for " + propertySimple + "...");
FormItem valueItem = null; @@ -1004,6 +1024,7 @@ public class ConfigurationEditor extends LocatableVLayout { List<Validator> validators = buildValidators(propertyDefinition, propertySimple); valueItem.setValidators(validators.toArray(new Validator[validators.size()]));
+ valueItem.setDisabled(isReadOnly(propertyDefinition) || isUnset(propertyDefinition, propertySimple)); /* Click handlers seem to be turned off for disabled fields... need an alternative valueItem.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() { @@ -1017,27 +1038,29 @@ public class ConfigurationEditor extends LocatableVLayout { */
valueItem.setShowTitle(false); - valueItem.setDisabled(isReadOnly(propertyDefinition) || isUnset(propertyDefinition, propertySimple)); valueItem.setWidth(220);
final FormItem finalValueItem = valueItem;
finalValueItem.addChangedHandler(new ChangedHandler() { public void onChanged(ChangedEvent changedEvent) { - boolean wasValidBefore = ConfigurationEditor.this.invalidPropertyNames.isEmpty(); propertySimple.setErrorMessage(null); + + boolean wasValidBefore = ConfigurationEditor.this.invalidPropertyNames.isEmpty(); + Property topLevelProperty = getTopLevelProperty(propertySimple); if (changedEvent.getItem().validate()) { - ConfigurationEditor.this.invalidPropertyNames.remove(propertySimple.getName()); - propertySimple.setValue(changedEvent.getValue()); + ConfigurationEditor.this.invalidPropertyNames.remove(topLevelProperty.getName()); + propertySimple.setValue(changedEvent.getValue()); } else { - ConfigurationEditor.this.invalidPropertyNames.add(propertySimple.getName()); + ConfigurationEditor.this.invalidPropertyNames.add(topLevelProperty.getName()); } boolean isValidNow = ConfigurationEditor.this.invalidPropertyNames.isEmpty(); + boolean validationStateChanged = (isValidNow != wasValidBefore); - for (PropertyValueChangeListener validationStateChangeListener : ConfigurationEditor.this.validationStateChangeListeners) { + for (PropertyValueChangeListener propertyValueChangeListener : ConfigurationEditor.this.propertyValueChangeListeners) { PropertyValueChangeEvent event = new PropertyValueChangeEvent(propertySimple, propertyDefinition, validationStateChanged, ConfigurationEditor.this.invalidPropertyNames); - validationStateChangeListener.propertyValueChanged(event); + propertyValueChangeListener.propertyValueChanged(event); } } }); @@ -1045,9 +1068,19 @@ public class ConfigurationEditor extends LocatableVLayout { return valueItem; }
- private boolean isUnset(PropertyDefinitionSimple propertyDefinition, PropertySimple propertySimple) { - return (!propertyDefinition.isRequired() && - (propertySimple == null || propertySimple.getStringValue() == null)); + private static Property getTopLevelProperty(PropertySimple propertySimple) { + Property currentProperty = propertySimple; + while (currentProperty.getConfiguration() == null) { + if (currentProperty.getParentList() != null) { + currentProperty = currentProperty.getParentList(); + } else if (currentProperty.getParentMap() != null) { + currentProperty = currentProperty.getParentMap(); + } else { + Log.error("Property " + currentProperty + " has no parent."); + break; + } + } + return currentProperty; }
private FormItem buildUnsetItem(PropertyDefinitionSimple propertyDefinition, final PropertySimple property, @@ -1083,6 +1116,11 @@ public class ConfigurationEditor extends LocatableVLayout { return item; }
+ private boolean isUnset(PropertyDefinitionSimple propertyDefinition, PropertySimple propertySimple) { + return (!propertyDefinition.isRequired() && + (propertySimple == null || propertySimple.getStringValue() == null)); + } + private boolean isReadOnly(PropertyDefinition propertyDefinition) { return propertyDefinition.isReadOnly() || this.readOnly; } @@ -1131,14 +1169,14 @@ public class ConfigurationEditor extends LocatableVLayout { private void displayMapEditor(String locatorId, final ListGrid summaryTable, final Record existingRecord, PropertyDefinitionMap definition, final PropertyList list, PropertyMap map) {
- final List<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(definition + final List<PropertyDefinition> memberDefinitions = new ArrayList<PropertyDefinition>(definition .getPropertyDefinitions().values()); - - Collections.sort(definitions, new PropertyDefinitionComparator()); + Collections.sort(memberDefinitions, new PropertyDefinitionComparator());
final boolean newRow = map == null; - if (newRow) + if (newRow) { map = new PropertyMap(definition.getName()); + }
final PropertyMap finalMap = map; final PropertyMap copy = finalMap.deepCopy(true); @@ -1146,7 +1184,7 @@ public class ConfigurationEditor extends LocatableVLayout { LocatableVLayout layout = new LocatableVLayout(locatorId); layout.setHeight100();
- DynamicForm childForm = buildPropertiesForm(locatorId + "_Child", definitions, finalMap); + final DynamicForm childForm = buildPropertiesForm(locatorId + "_Child", memberDefinitions, finalMap); childForm.setHeight100(); layout.addMember(childForm);
@@ -1159,24 +1197,21 @@ public class ConfigurationEditor extends LocatableVLayout { popup.setShowCloseButton(false); popup.centerInPage();
- final IButton saveButton = new IButton("Save"); + final IButton okButton = new IButton("OK"); + okButton.disable(); // saveButton.setID("config_structured_button_save"); - saveButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() { + okButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() { public void onClick(ClickEvent clickEvent) { - if (newRow) { list.add(finalMap); - ListGridRecord record = buildSummaryRecord(definitions, finalMap); - - com.allen_sauer.gwt.log.client.Log.info("here"); + ListGridRecord record = buildSummaryRecord(memberDefinitions, finalMap); try { summaryTable.addData(record); - com.allen_sauer.gwt.log.client.Log.info("there"); } catch (Exception e) { e.printStackTrace(); } } else { - for (PropertyDefinition subDef : definitions) { + for (PropertyDefinition subDef : memberDefinitions) { PropertyDefinitionSimple subDefSimple = (PropertyDefinitionSimple) subDef; PropertySimple propertySimple = ((PropertySimple) finalMap.get(subDefSimple.getName())); existingRecord.setAttribute(subDefSimple.getName(), propertySimple != null ? propertySimple @@ -1191,7 +1226,13 @@ public class ConfigurationEditor extends LocatableVLayout { // summaryTable.redraw(); // summaryTable.addData(); popup.destroy(); + } + });
+ // Only enable the OK button if all properties are valid. + childForm.addItemChangedHandler(new ItemChangedHandler() { + public void onItemChanged(ItemChangedEvent itemChangedEvent) { + okButton.setDisabled(!childForm.validate()); } });
@@ -1208,13 +1249,12 @@ public class ConfigurationEditor extends LocatableVLayout { HLayout buttons = new HLayout(); buttons.setAlign(Alignment.CENTER); buttons.setMembersMargin(10); - buttons.setMembers(saveButton, cancelButton); + buttons.setMembers(okButton, cancelButton); layout.addMember(buttons);
popup.addItem(layout);
popup.show(); - }
private static class PropertyDefinitionComparator implements Comparator<PropertyDefinition> { 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 f5afb2c..3f9f225 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 @@ -101,7 +101,7 @@ public class ResourceConfigurationEditView extends LocatableVLayout implements P editor = new ConfigurationEditor(this.extendLocatorId("Editor"), resource.getId(), resource.getResourceType().getId()); editor.setOverflow(Overflow.AUTO); - editor.addValidationStateChangeListener(this); + editor.addPropertyValueChangeListener(this); editor.setReadOnly(!this.resourcePermission.isConfigureWrite()); addMember(editor); } 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 116e1ad..1f1cc52 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 @@ -101,7 +101,7 @@ public class PluginConfigurationEditView extends LocatableVLayout implements Pro editor = new ConfigurationEditor(extendLocatorId("Editor"), resource.getId(), resource.getResourceType().getId(), ConfigurationEditor.ConfigType.plugin); editor.setOverflow(Overflow.AUTO); - editor.addValidationStateChangeListener(this); + editor.addPropertyValueChangeListener(this); editor.setReadOnly(!this.resourcePermission.isInventory()); addMember(editor); } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java index bfcb322..cc71a2c 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationFactory.java @@ -244,11 +244,11 @@ public abstract class TestConfigurationFactory { propMap3.put(new PropertySimple("Integer", Integer.MAX_VALUE)); configuration.put(new PropertyList("ListOfMaps", propMap2, propMap3));
- PropertyMap propMap4 = new PropertyMap("MapOfSimples"); + PropertyMap propMap4 = new PropertyMap("MapOfSimplesInReadOnlyList"); propMap4.put(new PropertySimple("String1", "A")); propMap4.put(new PropertySimple("String2", "B")); propMap4.put(new PropertySimple("Integer", 999)); - PropertyMap propMap5 = new PropertyMap("MapOfSimples"); + PropertyMap propMap5 = new PropertyMap("MapOfSimplesInReadOnlyList"); propMap5.put(new PropertySimple("String1", "a")); propMap5.put(new PropertySimple("String2", "b")); propMap5.put(new PropertySimple("Integer", 0)); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java index 0349718..2fd5dfa 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/TestConfigurationView.java @@ -86,24 +86,6 @@ public class TestConfigurationView reloadConfiguration(); }
- private void reloadConfiguration() { - this.saveButton.disable(); - if (editor != null) { - editor.destroy(); - removeMember(editor); - } - - editor = new ConfigurationEditor(extendLocatorId("Editor"), this.configurationDefinition, this.configuration); - editor.setOverflow(Overflow.AUTO); - editor.addValidationStateChangeListener(this); - addMember(editor); - } - - private void save() { - CoreGUI.getMessageCenter().notify( - new Message("Configuration updated.", "Test configuration updated.")); - } - @Override public void propertyValueChanged(PropertyValueChangeEvent event) { MessageCenter messageCenter = CoreGUI.getMessageCenter(); @@ -126,4 +108,23 @@ public class TestConfigurationView this.saveButton.enable(); } } + + private void reloadConfiguration() { + this.saveButton.disable(); + if (editor != null) { + editor.destroy(); + removeMember(editor); + } + + editor = new ConfigurationEditor(extendLocatorId("Editor"), this.configurationDefinition, this.configuration); + editor.setOverflow(Overflow.AUTO); + editor.addPropertyValueChangeListener(this); + addMember(editor); + } + + private void save() { + CoreGUI.getMessageCenter().notify( + new Message("Configuration updated.", "Test configuration updated.")); + reloadConfiguration(); + } } diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java index 37dddbb..ccc5eeb 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/configuration/test/TestConfigurationFactory.java @@ -236,11 +236,11 @@ public abstract class TestConfigurationFactory { propMap3.put(new PropertySimple("Integer", Integer.MAX_VALUE)); configuration.put(new PropertyList("ListOfMaps", propMap2, propMap3));
- PropertyMap propMap4 = new PropertyMap("MapOfSimples"); + PropertyMap propMap4 = new PropertyMap("MapOfSimplesInReadOnlyList"); propMap4.put(new PropertySimple("String1", "A")); propMap4.put(new PropertySimple("String2", "B")); propMap4.put(new PropertySimple("Integer", 999)); - PropertyMap propMap5 = new PropertyMap("MapOfSimples"); + PropertyMap propMap5 = new PropertyMap("MapOfSimplesInReadOnlyList"); propMap5.put(new PropertySimple("String1", "a")); propMap5.put(new PropertySimple("String2", "b")); propMap5.put(new PropertySimple("Integer", 0));
commit 978b466848e1bd299f191f370ca8c10e57f0f557 Author: John Sanda jsanda@redhat.com Date: Mon Oct 4 20:07:50 2010 -0400
Adding test to verify options are added to an upgraded property
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java index 2324a43..1f72c06 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java @@ -35,6 +35,7 @@ import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor; import org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinition; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionEnumeration; import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; @@ -109,6 +110,21 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test { }
@Test + public void updatePropertyWithAddedOptions() { + initConfigDefs("servers[name='ServerWithAddedOptions']", "UpdatedPropertyWithAddedOptions"); + + String propertyName = "mySimple"; + PropertyDefinitionSimple expectedProperty = updatedConfigDef.getPropertyDefinitionSimple(propertyName); + List<PropertyDefinitionEnumeration> expected = expectedProperty.getEnumeratedValues(); + + PropertyDefinitionSimple actualProperty = originalConfigDef.getPropertyDefinitionSimple(propertyName); + List<PropertyDefinitionEnumeration> actual = actualProperty.getEnumeratedValues(); + + // TODO Need to verify order here as well + AssertUtils.assertCollectionEqualsNoOrder(expected, actual, "Options should have been added to property"); + } + + @Test public void addNewGroup() { initConfigDefs("servers[name='GroupTests']", "GroupTests");
diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml index 23f3a1b..5a1fe11 100644 --- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml +++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml @@ -19,6 +19,12 @@ </plugin-configuration> </server>
+ <server name="ServerWithAddedOptions"> + <plugin-configuration> + <c:simple-property name="mySimple"/> + </plugin-configuration> + </server> + <server name="GroupTests"> <plugin-configuration> <c:group name="existingGroup"> diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml index 4c61512..564c68c 100644 --- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml +++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml @@ -26,6 +26,17 @@ </plugin-configuration> </server>
+ <server name="ServerWithAddedOptions"> + <plugin-configuration> + <c:simple-property name="mySimple"> + <c:property-options> + <c:option name="x" value="1"/> + <c:option name="y" value="2"/> + </c:property-options> + </c:simple-property> + </plugin-configuration> + </server> + <server name="GroupTests"> <plugin-configuration> <c:group name="existingGroup">
commit 885a5f526a3868a44d3f07f61c5df1ed1ef4ae16 Author: John Mazzitelli mazz@redhat.com Date: Mon Oct 4 17:02:47 2010 -0400
implement the new alert-role server plugin notification editor. this needs to be tested to make sure the sender still works. but the notification configuration is consistent with how it was before so it should work
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java index 3237c49..2d18670 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java @@ -22,10 +22,13 @@ */ package org.rhq.core.domain.criteria;
+import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType;
import org.rhq.core.domain.authz.Role; +import org.rhq.core.domain.util.CriteriaUtils; import org.rhq.core.domain.util.PageOrdering;
/** @@ -39,7 +42,8 @@ public class RoleCriteria extends Criteria { private Integer filterId; private String filterDescription; private String filterName; - private Integer filterSubjectId; + private Integer filterSubjectId; // needs overrides + private List<Integer> filterIds; // needs overrides
private boolean fetchPermissions; private boolean fetchResourceGroups; @@ -54,6 +58,8 @@ public class RoleCriteria extends Criteria { + " FROM Role innerRole " // + " JOIN innerRole.subjects innerSubject " // + " WHERE innerSubject.id = ? )"); + + filterOverrides.put("ids", "id IN ( ? )"); }
@Override @@ -77,6 +83,10 @@ public class RoleCriteria extends Criteria { this.filterSubjectId = filterSubjectId; }
+ public void addFilterIds(Integer... filterIds) { + this.filterIds = CriteriaUtils.getListIgnoringNulls(filterIds); + } + /** * Requires MANAGE_SECURITY * @param fetchSubjects diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java index 7d8745d..40bd990 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java @@ -220,7 +220,7 @@ public class NewNotificationEditor extends LocatableDynamicForm { if ("System Users".equals(sender)) { newCanvas = new SystemUsersNotificationSenderForm(newLocatorId, notificationToEdit, sender); } else if ("System Roles".equals(sender)) { - newCanvas = null; // TODO + newCanvas = new SystemRolesNotificationSenderForm(newLocatorId, notificationToEdit, sender); } else if ("Resource Operations".equals(sender)) { newCanvas = null; // TODO } else { diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java new file mode 100644 index 0000000..fe4cf36 --- /dev/null +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemRolesNotificationSenderForm.java @@ -0,0 +1,202 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser General Public License along with this program; + * if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.rhq.enterprise.gui.coregui.client.alert.definitions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.smartgwt.client.data.Criteria; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.grid.ListGridRecord; + +import org.rhq.core.domain.alert.notification.AlertNotification; +import org.rhq.core.domain.authz.Role; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.criteria.RoleCriteria; +import org.rhq.core.domain.util.PageList; +import org.rhq.enterprise.gui.coregui.client.CoreGUI; +import org.rhq.enterprise.gui.coregui.client.admin.roles.RolesDataSource; +import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector; +import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; +import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource; + +/** + * This notification form will be used for the System Roles sender. This form lets + * you pick roles that the sender will send notifications to. + * + * @author John Mazzitelli + */ +public class SystemRolesNotificationSenderForm extends AbstractNotificationSenderForm { + + // the alert configuration property name where the IDs are stored in |-separated form + private static final String PROPNAME = "roleId"; + + private RoleSelector selector; + + public SystemRolesNotificationSenderForm(String locatorId, AlertNotification notif, String sender) { + super(locatorId, notif, sender); + } + + @Override + protected void onInit() { + super.onInit(); + + String roleIds = getConfiguration().getSimpleValue(PROPNAME, ""); // we know the role plugin defines this + if (roleIds != null && roleIds.length() > 0) { + try { + List<Integer> ids = unfence(roleIds, Integer.class); + RoleCriteria criteria = new RoleCriteria(); + criteria.addFilterIds(ids.toArray(new Integer[ids.size()])); + GWTServiceLookup.getRoleService().findRolesByCriteria(criteria, new AsyncCallback<PageList<Role>>() { + @Override + public void onSuccess(PageList<Role> result) { + createNewSelector(result); + } + + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler() + .handleError("Cannot determine current roles - starting empty", caught); + createNewSelector(null); + } + }); + } catch (Exception e) { + CoreGUI.getErrorHandler().handleError("Cannot use current roles - starting empty", e); + createNewSelector(null); + } + } else { + createNewSelector(null); + } + } + + private void createNewSelector(Collection<Role> preselectedRoles) { + String selectorLocatorId = extendLocatorId("roleSelector"); + selector = new RoleSelector(selectorLocatorId, preselectedRoles); + selector.setWidth(400); + selector.setHeight(300); + addMember(selector); + markForRedraw(); + } + + @Override + public boolean validate() { + if (selector != null) { + try { + HashSet<Integer> selectedIds = selector.getSelection(); + String newPropValue = fence(selectedIds); + getConfiguration().put(new PropertySimple(PROPNAME, newPropValue)); + return true; + } catch (Exception e) { + CoreGUI.getErrorHandler().handleError("Cannot save the selected roles", e); + return false; + } + } + return true; + } + + @SuppressWarnings("unchecked") + private <T> List<T> unfence(String fencedData, Class<T> type) { + String delimiter = "\|"; + String[] elements = fencedData.split(delimiter); + List<T> results = new ArrayList<T>(elements.length); + + if (Integer.class.equals(type)) { + for (String next : elements) { + if (next.length() != 0) { + results.add((T) Integer.valueOf(next)); + } + } + } else if (String.class.equals(type)) { + for (String next : elements) { + if (next.length() != 0) { + results.add((T) next); + } + } + } else { + throw new IllegalArgumentException("No support for unfencing data of type " + type); + } + return results; + } + + /** + * Takes the list of elements e1, e2, e3 and fences + * them with '|' delimiters such that the result looks + * like "|e1|e2|e3|" + */ + private String fence(Collection<?> elements) { + if (elements.size() == 0) { + return ""; + } + StringBuilder builder = new StringBuilder(); + builder.append('|'); + for (Object next : elements) { + builder.append(String.valueOf(next)).append('|'); + } + return builder.toString(); + } + + private class RoleSelector extends AbstractSelector<Role> { + + public RoleSelector(String id, Collection<Role> roles) { + super(id); + if (roles != null) { + ListGridRecord[] data = (new RolesDataSource()).buildRecords(roles); + setAssigned(data); + } + } + + @Override + protected RPCDataSource<Role> getDataSource() { + return new SelectedRolesDataSource(); + } + + @Override + protected DynamicForm getAvailableFilterForm() { + return null; // No Filters Currently + } + + @Override + protected Criteria getLatestCriteria(DynamicForm availableFilterForm) { + return null; // No Filters Currently + } + + public class SelectedRolesDataSource extends RolesDataSource { + + @Override + public ListGridRecord[] buildRecords(Collection<Role> roles) { + ListGridRecord[] records = super.buildRecords(roles); + for (ListGridRecord record : records) { + if (selection.contains(record.getAttributeAsInt("id"))) { + record.setEnabled(false); + } + } + return records; + } + } + + } +} diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java deleted file mode 100644 index a7f556e..0000000 --- a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesBackingBean.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.server.plugins.alertRoles; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.rhq.core.domain.authz.Role; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.util.PageControl; -import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; -import org.rhq.enterprise.server.plugin.pc.alert.CustomAlertSenderBackingBean; -import org.rhq.enterprise.server.util.LookupUtil; - -/** - * Backing Bean for the roles sender alert sender plugin custom UI - * @author Joseph Marques - */ -public class RolesBackingBean extends CustomAlertSenderBackingBean { - - private Map<String, String> available; - private List<String> currentRoles; - private static final String ROLE_ID = "roleId"; - - @Override - public void loadView() { - // get available/all subjects - List<Role> allRoles = LookupUtil.getRoleManager().findRoles(new PageControl()); - available = new HashMap<String, String>(); - for (Role role : allRoles) { - String roleId = String.valueOf(role.getId()); - available.put(role.getName(), roleId); - } - - // get current subjects - String subjectString = alertParameters.getSimpleValue(ROLE_ID, ""); - currentRoles = AlertSender.unfence(subjectString, String.class); - } - - @Override - public void saveView() { - String roleIds = AlertSender.fence(currentRoles); - - PropertySimple p = alertParameters.getSimple(ROLE_ID); - if (p == null) { - p = new PropertySimple(ROLE_ID, roleIds); - alertParameters.put(p); - } else { - p.setStringValue(roleIds); - } - - alertParameters = persistConfiguration(alertParameters); - } - - public List<String> getCurrentRoles() { - return currentRoles; - } - - public void setCurrentRoles(List<String> currentRoles) { - this.currentRoles = currentRoles; - } - - public Map<String, String> getAvailableRolesMap() { - return available; - } -} diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml index 7d7551c..4e50100 100644 --- a/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/alert-roles/src/main/resources/META-INF/rhq-serverplugin.xml @@ -14,19 +14,13 @@ Used to send notifications to all users in the selected system roles. </serverplugin:help>
- <!-- startup & tear down listener, + scheduled jobs - <serverplugin:plugin-component class="Foo" /> - --> - <!-- How does this sender show up in drop downs etc --> <short-name>System Roles</short-name>
<!-- Class that does the actual sending --> <plugin-class>RolesSender</plugin-class>
- <custom-ui> - <ui-snippet-name>roles.xhtml</ui-snippet-name> - <backing-bean-class>RolesBackingBean</backing-bean-class> - <backing-bean-name>rolesBean</backing-bean-name> - </custom-ui> + <alert-configuration> + <c:simple-property name="roleId" type="string" required="true" description="The roles (ids are |-separated) to be notified"/> + </alert-configuration> </alert-plugin> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml b/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml deleted file mode 100644 index f807414..0000000 --- a/modules/enterprise/server/plugins/alert-roles/src/main/resources/roles.xhtml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:a4j="https://richfaces.org/a4j" - xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E - -<body> - <rich:pickList fastMoveControlsVisible="false" - sourceListWidth="200px" - targetListWidth="200px" - copyControlLabel="Add Roles" - removeControlLabel="Remove Roles" - value="#{rolesBean.currentRoles}"> - <f:selectItems value="#{rolesBean.availableRolesMap}" /> - </rich:pickList> -</body> - -</html> \ No newline at end of file
commit c1145e500bd70a985a0b609de0f42655902d23a6 Author: Ian Springer ian.springer@redhat.com Date: Mon Oct 4 16:58:21 2010 -0400
finish support for top-level maps - both static and dynamic/open; disable window logger
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml index ed2ce42..c486f1d 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml @@ -38,7 +38,9 @@ 2. In hosted mode, the windows are not automatically closed, although you can easily close them manually in the usual way --> + <!-- <set-property name="log_WindowLogger" value="ENABLED" /> + -->
<!-- You probably will want to disable the default `DivLogger` as well: 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 fdc2d9c..d9c3dd7 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 @@ -19,6 +19,7 @@ package org.rhq.enterprise.gui.coregui.client.components.configuration;
import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; @@ -29,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Set;
+import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.data.Record; import com.smartgwt.client.types.Alignment; @@ -138,9 +140,12 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableTreeGrid; import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
/** + * A SmartGWT widget for editing an RHQ {@link Configuration}, which conforms to a {@link ConfigurationDefinition}. + * * @author Greg Hinkle * @author Ian Springer */ +@SuppressWarnings({"UnnecessarySemicolon"}) public class ConfigurationEditor extends LocatableVLayout { private ConfigurationGWTServiceAsync configurationService = GWTServiceLookup.getConfigurationService();
@@ -170,7 +175,6 @@ public class ConfigurationEditor extends LocatableVLayout { public static enum ConfigType { plugin, resource } - ; // Need this extra semicolon for the qdox parser
public ConfigurationEditor(String locatorId) { @@ -330,6 +334,11 @@ public class ConfigurationEditor extends LocatableVLayout { this.markForRedraw(); }
+ public void reset() { + this.configuration = this.originalConfiguration; + reload(); + } + protected HLayout buildRawPane() {
LocatableHLayout layout = new LocatableHLayout(extendLocatorId("Raw")); @@ -457,7 +466,6 @@ public class ConfigurationEditor extends LocatableVLayout { }
public SectionStackSection buildGroupSection(String locatorId, PropertyGroupDefinition group) { - SectionStackSection section; if (group == null) { section = new SectionStackSection("General Properties"); @@ -473,18 +481,25 @@ public class ConfigurationEditor extends LocatableVLayout { section.setExpanded(!group.isDefaultHidden()); }
- ArrayList<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(((group == null) ? definition - .getNonGroupedProperties() : definition.getPropertiesInGroup(group.getName()))); - Collections.sort(definitions, new PropertyDefinitionComparator()); + List<PropertyDefinition> propertyDefinitions = new ArrayList<PropertyDefinition>(((group == null) ? definition + .getNonGroupedProperties() : definition.getPropertiesInGroup(group.getName())));
- DynamicForm form = buildPropertiesForm(locatorId + "_Props", definitions, configuration); + DynamicForm form = buildPropertiesForm(locatorId + "_Props", propertyDefinitions, configuration);
section.addItem(form); return section; }
- private DynamicForm buildPropertiesForm(String locatorId, List<PropertyDefinition> definitions, + private DynamicForm buildPropertiesForm(String locatorId, Collection<PropertyDefinition> propertyDefinitions, AbstractPropertyMap propertyMap) { + List<PropertyDefinition> propertyDefinitionsList; + if (!(propertyDefinitions instanceof List)) { + propertyDefinitionsList = new ArrayList<PropertyDefinition>(propertyDefinitions); + } else { + propertyDefinitionsList = (List<PropertyDefinition>)propertyDefinitions; + } + Collections.sort(propertyDefinitionsList, new PropertyDefinitionComparator()); + LocatableDynamicForm form = new LocatableDynamicForm(locatorId); form.setValuesManager(valuesManager); form.setValidateOnChange(true); @@ -503,11 +518,17 @@ public class ConfigurationEditor extends LocatableVLayout { form.setCellPadding(5); form.setColWidths(190, 28, 210);
- ArrayList<FormItem> fields = new ArrayList<FormItem>(); + List<FormItem> fields = new ArrayList<FormItem>(); + addItemsForPropertiesRecursively(locatorId, propertyDefinitionsList, propertyMap, fields); + form.setFields(fields.toArray(new FormItem[fields.size()])); + + return form; + }
+ private void addItemsForPropertiesRecursively(String locatorId, Collection<PropertyDefinition> propertyDefinitions, + AbstractPropertyMap propertyMap, List<FormItem> fields) { boolean odd = true; - - for (PropertyDefinition propertyDefinition : definitions) { + for (PropertyDefinition propertyDefinition : propertyDefinitions) { Property property = propertyMap.get(propertyDefinition.getName()); if (property == null) { if (propertyDefinition instanceof PropertyDefinitionSimple) { @@ -515,17 +536,17 @@ public class ConfigurationEditor extends LocatableVLayout { propertyMap.put(property); } } - addItems(locatorId + "_" + propertyDefinition.getName(), fields, propertyDefinition, property, odd); + addItemsForPropertyRecursively(locatorId + "_" + propertyDefinition.getName(), propertyDefinition, property, + odd, fields); odd = !odd; } - - form.setFields(fields.toArray(new FormItem[fields.size()])); - - return form; }
- public void addItems(String locatorId, ArrayList<FormItem> fields, PropertyDefinition propertyDefinition, - Property property, boolean oddRow) { + public void addItemsForPropertyRecursively(String locatorId, PropertyDefinition propertyDefinition, + Property property, + boolean oddRow, + List<FormItem> fields) { + List<FormItem> fieldsForThisProperty = new ArrayList<FormItem>();
StaticTextItem nameItem = new StaticTextItem(); nameItem.setStartRow(true); @@ -534,30 +555,50 @@ public class ConfigurationEditor extends LocatableVLayout { .getName()) + "</b>"; nameItem.setValue(title); nameItem.setShowTitle(false); - nameItem.setCellStyle(oddRow ? "OddRow" : "EvenRow");
+ fieldsForThisProperty.add(nameItem); fields.add(nameItem);
FormItem valueItem; if (propertyDefinition instanceof PropertyDefinitionSimple) { - valueItem = buildSimpleField(fields, (PropertyDefinitionSimple) propertyDefinition, oddRow, property); + PropertyDefinitionSimple propertyDefinitionSimple = (PropertyDefinitionSimple)propertyDefinition; + PropertySimple propertySimple = (PropertySimple)property; + + valueItem = buildSimpleField(propertyDefinitionSimple, propertySimple); + + FormItem unsetItem = buildUnsetItem(propertyDefinitionSimple, propertySimple, valueItem); + fieldsForThisProperty.add(unsetItem); + fields.add(unsetItem); + + fieldsForThisProperty.add(valueItem); fields.add(valueItem);
StaticTextItem descriptionItem = new StaticTextItem(); descriptionItem.setValue(propertyDefinition.getDescription()); descriptionItem.setShowTitle(false); descriptionItem.setEndRow(true); - descriptionItem.setCellStyle(oddRow ? "OddRow" : "EvenRow"); + fieldsForThisProperty.add(descriptionItem); fields.add(descriptionItem); } else if (propertyDefinition instanceof PropertyDefinitionList) { if (((PropertyDefinitionList) propertyDefinition).getMemberDefinition() instanceof PropertyDefinitionMap) { // List of Maps is a specially supported case with summary fields as columns in a table - buildListOfMapsField(locatorId, fields, - (PropertyDefinitionMap) ((PropertyDefinitionList) propertyDefinition).getMemberDefinition(), - oddRow, (PropertyList) property); + // Note: This field spans 3 columns. + CanvasItem listOfMapsItem = buildListOfMapsField(locatorId, + (PropertyDefinitionMap)((PropertyDefinitionList)propertyDefinition).getMemberDefinition(), + oddRow, (PropertyList)property); + fields.add(listOfMapsItem); } + // TODO (ips): Add support for lists of simples. } else if (propertyDefinition instanceof PropertyDefinitionMap) { - buildMapsField(fields, (PropertyDefinitionMap) propertyDefinition, (PropertyMap) property); + // Note: This field spans 3 columns. + FormItem mapField = + buildMapField(locatorId, (PropertyDefinitionMap)propertyDefinition, (PropertyMap)property); + fields.add(mapField); + } + + // Set row background color. + for (FormItem field : fieldsForThisProperty) { + field.setCellStyle(oddRow ? "OddRow" : "EvenRow"); } }
@@ -565,13 +606,39 @@ public class ConfigurationEditor extends LocatableVLayout { return this.invalidPropertyNames; }
- private void buildMapsField(ArrayList<FormItem> fields, PropertyDefinitionMap propertyDefinitionMap, - final PropertyMap propertyMap) { + private FormItem buildMapField(String parentLocatorId, PropertyDefinitionMap propertyDefinitionMap, + final PropertyMap propertyMap) { + Canvas canvas; + Map<String, PropertyDefinition> memberPropertyDefinitions = propertyDefinitionMap.getPropertyDefinitions(); + String locatorId = parentLocatorId + "_" + propertyDefinitionMap.getName(); + if (memberPropertyDefinitions == null || memberPropertyDefinitions.isEmpty()) { + canvas = buildDynamicMapField(locatorId, propertyDefinitionMap, propertyMap); + } else { + canvas = buildStaticMapField(locatorId, propertyDefinitionMap, propertyMap); + } + CanvasItem canvasItem = buildComplexPropertyField(canvas); + + return canvasItem; + } + + private CanvasItem buildComplexPropertyField(Canvas canvas) { + CanvasItem canvasItem = new CanvasItem(); + canvasItem.setCanvas(canvas); + canvasItem.setColSpan(3); + canvasItem.setEndRow(true); + canvasItem.setShowTitle(false); + return canvasItem; + } + + private Canvas buildDynamicMapField(String parentLocatorId, PropertyDefinitionMap propertyDefinitionMap, + final PropertyMap propertyMap) { + Log.debug("Building dynamic map field for " + propertyMap + "..."); + // create the property grid final PropertyGrid propertyGrid = new PropertyGrid(); propertyGrid.getNameField().setName("Name"); propertyGrid.getValuesField().setName("Value"); - + // create the editors Map<String, FormItem> editorsMap = new HashMap<String, FormItem>(); TextItem textEditor = new TextItem(); @@ -580,27 +647,26 @@ public class ConfigurationEditor extends LocatableVLayout { // set the editors and attribute name where to find the record type propertyGrid.setEditorsMap("fieldType", editorsMap);
- if (propertyDefinitionMap != null) { - ListGridRecord[] records = new ListGridRecord[propertyDefinitionMap.getPropertyDefinitions().size()]; - int i = 0; - // TODO (ips): For open maps, create the records based on props, not propDefs. - // TODO (ips): Render unset checkboxes amd descriptions for member props, just as we would for top-level simples. - for (PropertyDefinition propDef : propertyDefinitionMap.getPropertyDefinitions().values()) { - ListGridRecord record = new ListGridRecord(); - String propertyName = propDef.getName(); - record.setAttribute("Name", propertyName); - PropertySimple prop = propertyMap.getSimple(propertyName); - String value = (prop != null) ? prop.getStringValue() : null; - record.setAttribute("Value", value); - record.setAttribute("fieldType", "simpleText"); - record.setAttribute("readOnly", propDef.isReadOnly()); - records[i++] = record; + ListGridRecord[] records = new ListGridRecord[propertyMap.getMap().size()]; + int i = 0; + for (Property prop : propertyMap.getMap().values()) { + if (!(prop instanceof PropertySimple)) { + Log.warn("Unsupported Configuration permutation: PropertyMap " + propertyMap + + " contains non-simple member Property " + prop + " - skipping..."); + continue; } - propertyGrid.setData(records); + PropertySimple propSimple = (PropertySimple)prop; + ListGridRecord record = new ListGridRecord(); + String propertyName = prop.getName(); + record.setAttribute("Name", propertyName); + String value = propSimple.getStringValue(); + record.setAttribute("Value", value); + record.setAttribute("fieldType", "simpleText"); + records[i++] = record; } + propertyGrid.setData(records);
VLayout canvas = new VLayout(); - canvas.addMember(propertyGrid);
// Footer @@ -610,8 +676,8 @@ public class ConfigurationEditor extends LocatableVLayout { footer.setMembersMargin(15); canvas.addMember(footer);
- // Properties can only be added to or deleted from non-read-only "open" maps. - if (propertyDefinitionMap.getPropertyDefinitions().isEmpty() && !propertyDefinitionMap.isReadOnly()) { + // Properties can only be added to or deleted from non-read-only dynamic maps. + if (!propertyDefinitionMap.isReadOnly()) { final IButton deleteButton = new LocatableIButton(extendLocatorId(propertyMap.getName()), "Delete"); deleteButton.setDisabled(true); deleteButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() { @@ -688,19 +754,21 @@ public class ConfigurationEditor extends LocatableVLayout { } });
- propertyGrid.draw(); - - CanvasItem canvasItem = new CanvasItem(); - canvasItem.setCanvas(canvas); - // item.setHeight(500); - canvasItem.setColSpan(3); - canvasItem.setEndRow(true); - canvasItem.setShowTitle(false); - fields.add(canvasItem); + return canvas; + } + + private Canvas buildStaticMapField(String parentLocatorId, PropertyDefinitionMap propertyDefinitionMap, + PropertyMap propertyMap) { + Log.debug("Building static map field for " + propertyMap + "..."); + + return buildPropertiesForm(parentLocatorId, propertyDefinitionMap.getPropertyDefinitions().values(), propertyMap); + }
- private void buildListOfMapsField(final String locatorId, ArrayList<FormItem> fields, - final PropertyDefinitionMap propertyDefinition, boolean oddRow, final PropertyList propertyList) { + private CanvasItem buildListOfMapsField(final String locatorId, + final PropertyDefinitionMap memberPropertyDefinitionMap, boolean oddRow, + final PropertyList propertyList) { + Log.debug("Building list-of-maps field for " + propertyList + "...");
final ListGrid summaryTable = new ListGrid(); // summaryTable.setID("config_summaryTable_" + propertyDefinition.getName()); @@ -711,7 +779,7 @@ public class ConfigurationEditor extends LocatableVLayout { summaryTable.setAutoFitData(Autofit.HORIZONTAL);
ArrayList<ListGridField> fieldsList = new ArrayList<ListGridField>(); - ArrayList<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(propertyDefinition + ArrayList<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>(memberPropertyDefinitionMap .getPropertyDefinitions().values()); Collections.sort(definitions, new PropertyDefinitionComparator());
@@ -757,7 +825,7 @@ public class ConfigurationEditor extends LocatableVLayout { public void onRecordClick(RecordClickEvent recordClickEvent) { com.allen_sauer.gwt.log.client.Log.info("You want to edit: " + recordClickEvent.getRecord()); displayMapEditor(locatorId + "_MapEdit", summaryTable, recordClickEvent.getRecord(), - propertyDefinition, propertyList, (PropertyMap) recordClickEvent.getRecord().getAttributeAsObject( + memberPropertyDefinitionMap, propertyList, (PropertyMap) recordClickEvent.getRecord().getAttributeAsObject( "_RHQ_PROPERTY")); } }); @@ -805,7 +873,7 @@ public class ConfigurationEditor extends LocatableVLayout { addRowButton.setIcon(Window.getImgURL("[SKIN]/actions/add.png")); addRowButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() { public void onClick(ClickEvent clickEvent) { - displayMapEditor(locatorId + "_MapEdit", summaryTable, null, propertyDefinition, propertyList, null); + displayMapEditor(locatorId + "_MapEdit", summaryTable, null, memberPropertyDefinitionMap, propertyList, null); } });
@@ -813,13 +881,9 @@ public class ConfigurationEditor extends LocatableVLayout {
summaryTableHolder.setMembers(summaryTable, toolStrip);
- CanvasItem item = new CanvasItem(); - item.setCanvas(summaryTableHolder); - // item.setHeight(500); - item.setColSpan(3); - item.setEndRow(true); - item.setShowTitle(false); - fields.add(item); + CanvasItem item = buildComplexPropertyField(summaryTableHolder); + + return item; }
private ListGridRecord[] buildSummaryRecords(PropertyList propertyList, ArrayList<PropertyDefinition> definitions) { @@ -827,7 +891,6 @@ public class ConfigurationEditor extends LocatableVLayout { int i = 0; for (Property row : propertyList.getList()) { PropertyMap rowMap = (PropertyMap) row; - ListGridRecord record = buildSummaryRecord(definitions, rowMap); rows[i++] = record; } @@ -871,32 +934,13 @@ public class ConfigurationEditor extends LocatableVLayout { return record; }
- private FormItem buildSimpleField(ArrayList<FormItem> fields, final PropertyDefinitionSimple propertyDefinition, - boolean oddRow, final Property property) { - final PropertySimple propertySimple = (PropertySimple) property; + private FormItem buildSimpleField(final PropertyDefinitionSimple propertyDefinition, + final PropertySimple propertySimple + ) { + Log.debug("Building simple field for " + propertySimple + "...");
FormItem valueItem = null;
- boolean isUnset = (property == null || propertySimple.getStringValue() == null) - && propertyDefinition.isRequired() == false; - - CheckboxItem unsetItem = null; - if (!propertyDefinition.isRequired()) { - unsetItem = new CheckboxItem(); - unsetItem.setValue(isUnset); - unsetItem.setDisabled(readOnly); - unsetItem.setShowLabel(false); - unsetItem.setShowTitle(false); - unsetItem.setLabelAsTitle(false); - unsetItem.setColSpan(1); - unsetItem.setCellStyle(oddRow ? "OddRow" : "EvenRow"); - fields.add(unsetItem); - } else { - SpacerItem spacer = new SpacerItem(); - spacer.setCellStyle(oddRow ? "OddRow" : "EvenRow"); - fields.add(spacer); - } - List<PropertyDefinitionEnumeration> enumeratedValues = propertyDefinition.getEnumeratedValues(); if (enumeratedValues != null && !enumeratedValues.isEmpty()) {
@@ -911,7 +955,7 @@ public class ConfigurationEditor extends LocatableVLayout { valueItem = new RadioGroupItem(); } valueItem.setValueMap(valueOptions); - if (property != null) { + if (propertySimple != null) { valueItem.setValue(propertySimple.getStringValue()); } } else { @@ -921,15 +965,15 @@ public class ConfigurationEditor extends LocatableVLayout { case FILE: case DIRECTORY: valueItem = new TextItem(); - valueItem.setValue(property == null ? "" : propertySimple.getStringValue()); + valueItem.setValue(propertySimple == null ? "" : propertySimple.getStringValue()); break; case LONG_STRING: valueItem = new TextAreaItem(); - valueItem.setValue(property == null ? "" : propertySimple.getStringValue()); + valueItem.setValue(propertySimple == null ? "" : propertySimple.getStringValue()); break; case PASSWORD: valueItem = new PasswordItem(); - valueItem.setValue(property == null ? "" : propertySimple.getStringValue()); + valueItem.setValue(propertySimple == null ? "" : propertySimple.getStringValue()); break; case BOOLEAN: valueItem = new RadioGroupItem(); @@ -937,19 +981,19 @@ public class ConfigurationEditor extends LocatableVLayout { valMap.put("true", "Yes"); valMap.put("false", "No"); valueItem.setValueMap(valMap); - valueItem.setValue(property == null || propertySimple.getStringValue() == null ? false : propertySimple + valueItem.setValue(propertySimple == null || propertySimple.getStringValue() == null ? false : propertySimple .getBooleanValue()); break; case INTEGER: case LONG: valueItem = new IntegerItem(); - if (property != null && propertySimple.getStringValue() != null) + if (propertySimple != null && propertySimple.getStringValue() != null) valueItem.setValue(propertySimple.getLongValue()); break; case FLOAT: case DOUBLE: valueItem = new FloatItem(); - valueItem.setValue(property == null || propertySimple.getStringValue() == null ? 0 : propertySimple + valueItem.setValue(propertySimple == null || propertySimple.getStringValue() == null ? 0 : propertySimple .getDoubleValue()); break; } @@ -957,7 +1001,7 @@ public class ConfigurationEditor extends LocatableVLayout {
valueItem.setRequired(propertyDefinition.isRequired());
- List<Validator> validators = buildValidators(propertyDefinition, property); + List<Validator> validators = buildValidators(propertyDefinition, propertySimple); valueItem.setValidators(validators.toArray(new Validator[validators.size()]));
/* @@ -973,9 +1017,8 @@ public class ConfigurationEditor extends LocatableVLayout { */
valueItem.setShowTitle(false); - valueItem.setDisabled(isUnset || readOnly); + valueItem.setDisabled(isReadOnly(propertyDefinition) || isUnset(propertyDefinition, propertySimple)); valueItem.setWidth(220); - valueItem.setCellStyle(oddRow ? "OddRow" : "EvenRow");
final FormItem finalValueItem = valueItem;
@@ -992,30 +1035,56 @@ public class ConfigurationEditor extends LocatableVLayout { boolean isValidNow = ConfigurationEditor.this.invalidPropertyNames.isEmpty(); boolean validationStateChanged = (isValidNow != wasValidBefore); for (PropertyValueChangeListener validationStateChangeListener : ConfigurationEditor.this.validationStateChangeListeners) { - PropertyValueChangeEvent event = new PropertyValueChangeEvent(property, propertyDefinition, + PropertyValueChangeEvent event = new PropertyValueChangeEvent(propertySimple, propertyDefinition, validationStateChanged, ConfigurationEditor.this.invalidPropertyNames); validationStateChangeListener.propertyValueChanged(event); } } });
- if (unsetItem != null) { + return valueItem; + } + + private boolean isUnset(PropertyDefinitionSimple propertyDefinition, PropertySimple propertySimple) { + return (!propertyDefinition.isRequired() && + (propertySimple == null || propertySimple.getStringValue() == null)); + } + + private FormItem buildUnsetItem(PropertyDefinitionSimple propertyDefinition, final PropertySimple property, + final FormItem valueItem) { + FormItem item; + if (!propertyDefinition.isRequired()) { + CheckboxItem unsetItem = new CheckboxItem(); + boolean unset = isUnset(propertyDefinition, property); + unsetItem.setValue(unset); + unsetItem.setDisabled(isReadOnly(propertyDefinition)); + unsetItem.setShowLabel(false); + unsetItem.setShowTitle(false); + unsetItem.setLabelAsTitle(false); + unsetItem.setColSpan(1); + unsetItem.addChangeHandler(new ChangeHandler() { public void onChange(ChangeEvent changeEvent) { Boolean isUnset = (Boolean) changeEvent.getValue(); if (isUnset) { - finalValueItem.setDisabled(true); - finalValueItem.setValue((String) null); + valueItem.setDisabled(true); + valueItem.setValue((String) null); } else { - finalValueItem.setDisabled(false); - finalValueItem.focusInItem(); + valueItem.setDisabled(false); + valueItem.focusInItem(); } - propertySimple.setValue(finalValueItem.getValue()); + property.setValue(valueItem.getValue()); } }); + item = unsetItem; + } else { + item = new SpacerItem(); } + return item; + }
- return valueItem; + private boolean isReadOnly(PropertyDefinition propertyDefinition) { + return propertyDefinition.isReadOnly() || this.readOnly; }
private List<Validator> buildValidators(PropertyDefinitionSimple propertyDefinition, Property property) {
commit 5e74d53f806d7d87fa769647a5be15827077806f Author: John Sanda jsanda@redhat.com Date: Mon Oct 4 16:02:31 2010 -0400
Adding more tests, and adding call to set type on updated property definition
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java index 04a3995..f46c7a4 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java @@ -367,6 +367,8 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa if (newProperty instanceof PropertyDefinitionSimple) { PropertyDefinitionSimple newPDS = (PropertyDefinitionSimple) newProperty;
+ existingPDS.setType(newPDS.getType()); + // handle <property-options>? List<PropertyDefinitionEnumeration> existingOptions = existingPDS.getEnumeratedValues(); List<PropertyDefinitionEnumeration> newOptions = newPDS.getEnumeratedValues(); diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java index 5e2913b..2324a43 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBeanTest.java @@ -23,6 +23,8 @@
package org.rhq.enterprise.server.configuration.metadata;
+import java.util.List; + import javax.persistence.EntityManager; import javax.transaction.SystemException;
@@ -32,6 +34,9 @@ import org.testng.annotations.Test; import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor; import org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.configuration.definition.PropertyDefinition; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition; import org.rhq.enterprise.server.test.AbstractEJB3Test; @@ -40,7 +45,17 @@ import org.rhq.test.AssertUtils;
import static org.rhq.enterprise.server.configuration.metadata.PluginDescriptorUtil.loadPluginConfigDefFor; import static org.rhq.enterprise.server.configuration.metadata.PluginDescriptorUtil.loadPluginDescriptor; - +import static java.util.Arrays.asList; + +/** + * These are data-driven tests that exercise the plugin upgrade functionality around configurations such as plugin + * configurations and resource configurations. The data sets that are used are defined in two plugin descriptors. One + * is the original version and the other is the upgraded version. In order to avoid inter-dependencies between test + * methods, a separate plugin configuration should be used for each test method. A separate resource type is declared + * for each test, further documenting and delinating where each configuration is used. In the test methods, the + * original and updated coniguration definitions are initialized with an xpath expression that specifies the owning + * resource type. + */ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
PluginDescriptor originalDescriptor; @@ -62,7 +77,7 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test { }
@Test - public void addNewUngroupedPropertyDef() { + public void addNewUngroupedSimplePropertyDef() { initConfigDefs("servers[name='MyServer1']", "test");
String propertyName = "newUngroupedProperty"; @@ -93,13 +108,7 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test { "not change", expected, actual); }
- // This test fails with, - // - // PersistentObjectException: detached entity passed to persist - // - // I get the exception with both PropertyGroupDefinition and PropertyDefinitionSimple when I have tried various - // approaches to get past the exception. - @Test(enabled = false) + @Test public void addNewGroup() { initConfigDefs("servers[name='GroupTests']", "GroupTests");
@@ -107,14 +116,50 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test { findGroup("newGroup", originalConfigDef)); }
-// void assertGroupDefinitionExists() { -// for (PropertyGroupDefinition groupDef : originalConfigurationDef.getGroupDefinitions()) { -// if (groupDef.getName().equals("groupToBeRemoved")) { -// assertTrue(groupDef.getId() != 0); -// assertNotNull(entityMgr.find(PropertyGroupDefinition.class, groupDef.getId())); -// } -// } -// } + @Test + public void replaceMemberDefinitionOfPropertyList() { + initConfigDefs("servers[name='UpdatedPropertyList']", "ReplaceMemberDefinitionOfPropertyList"); + + String propertyName = "myList"; + PropertyDefinitionList expectedList = updatedConfigDef.getPropertyDefinitionList(propertyName); + PropertyDefinitionList actualList = originalConfigDef.getPropertyDefinitionList(propertyName); + + assertPropertyDefinitionMatches("The member definition should be replaced with the new version", expectedList, actualList); + } + + // Test is currently failing with, + // + // IllegalArgumentException: Removing a detached instance org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple + // + // I beleive that this is a problem with the test environment and not with production code. + @Test(enabled = false) + public void updateMapWithRemovedProperty() { + initConfigDefs("servers[name='UpdatedMapWithRemovedProperty']", "UpdateMapWithRemovedProperty"); + + String propertyName = "myMap"; + PropertyDefinitionMap map = originalConfigDef.getPropertyDefinitionMap(propertyName); + assertEquals("Expected property to be removed when it is removed from parent map", 0, + map.getPropertyDefinitions().size()); + } + + @Test + public void updateMapWithUpdatedProperty() { + initConfigDefs("servers[name='UpdatedMapWithUpdatedProperty']", "UpdateMapWithUpdatedProperty"); + + String propertyName = "propertyToUpdate"; + String mapPropertyName = "myMap"; + + PropertyDefinitionMap expectedMap = updatedConfigDef.getPropertyDefinitionMap(mapPropertyName); + PropertyDefinitionSimple expected = expectedMap.getPropertyDefinitionSimple(propertyName); + + PropertyDefinitionMap actualMap = originalConfigDef.getPropertyDefinitionMap(mapPropertyName); + PropertyDefinitionSimple actual = actualMap.getPropertyDefinitionSimple(propertyName); + + List<String> ignoredProperties = asList("id", "parentPropertyMapDefinition"); + + assertPropertyDefinitionMatches("Expected property who is a child of map to get updated and remain in the map", + expected, actual, ignoredProperties); + }
private void initConfigDefs(String path, String configName) { loadAndPersistConfigDefs(path, configName); @@ -132,8 +177,6 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test {
EntityManager entityMgr = getEntityManager(); entityMgr.persist(originalConfigDef); - //entityMgr.persist(updatedConfigDef); - getTransactionManager().commit(); } catch (Exception e) { try { @@ -146,21 +189,8 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test { }
private void updateConfigDef() { - try { - getTransactionManager().begin(); - - ConfigurationMetadataManagerLocal configMetadataMgr = LookupUtil.getConfigurationMetadataManager(); - configMetadataMgr.updateConfigurationDefinition(updatedConfigDef, originalConfigDef); - - getTransactionManager().commit(); - } catch (Exception e) { - try { - getTransactionManager().rollback(); - } catch (SystemException e1) { - throw new RuntimeException(e1); - } - throw new RuntimeException(e); - } + ConfigurationMetadataManagerLocal configMetadataMgr = LookupUtil.getConfigurationMetadataManager(); + configMetadataMgr.updateConfigurationDefinition(updatedConfigDef, originalConfigDef); }
private String getPackagePath() { @@ -176,33 +206,13 @@ public class ConfigurationMetadataManagerBeanTest extends AbstractEJB3Test { return null; }
- void assertPropertyDefinitionMatches(String msg, PropertyDefinitionSimple expected, - PropertyDefinitionSimple actual) { + void assertPropertyDefinitionMatches(String msg, PropertyDefinition expected, PropertyDefinition actual) { AssertUtils.assertPropertiesMatch(msg, expected, actual, "id", "configurationDefinition"); }
- @Test(enabled = false) - public void existingUngroupedPropertyDefShouldBeUpdated() throws Exception { - PropertyDefinitionSimple expected = updatedConfigDef.getPropertyDefinitionSimple("foo"); - PropertyDefinitionSimple actual = originalConfigDef.getPropertyDefinitionSimple("foo"); - - assertPropertyDefinitionMatches("Existing ungrouped property defs should be updated", expected, actual); - } - - @Test(enabled = false) - public void propertyDefNotInNewConfigurationDefShouldBeRemoved() throws Exception { - assertNull( - "A property def in the original configuration def that is removed in the new configuration def should be deleted", - originalConfigDef.getPropertyDefinitionSimple("propertyToBeRemoved") - ); + void assertPropertyDefinitionMatches(String msg, PropertyDefinition expected, PropertyDefinition actual, + List<String> ignoredProperties) { + AssertUtils.assertPropertiesMatch(msg, expected, actual, ignoredProperties); }
- @Test(enabled = false) - public void propertyGroupDefNotInNewConfigurationDefShouldBeRemoved() throws Exception { - for (PropertyGroupDefinition def : originalConfigDef.getGroupDefinitions()) { - if (def.getName().equals("groupToBeRemoved")) { - fail("Expected property group 'groupToBeRemoved' to be deleted since it is not in the new configuration def."); - } - } - } } diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml index dd8fcfa..23f3a1b 100644 --- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml +++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v1.xml @@ -26,4 +26,39 @@ </c:group> </plugin-configuration> </server> + + <server name="UpdatedPropertyList"> + <plugin-configuration> + <c:list-property name="myList" + displayName="My Test List" + readOnly="false" + description="Update Property List Test" + required="true" + min="1" + max="5"> + <c:simple-property name="myListMember" + type="double" + default="3.14" + description="PI"/> + </c:list-property> + </plugin-configuration> + </server> + + <server name="UpdatedMapWithRemovedProperty"> + <plugin-configuration> + <c:map-property name="myMap"> + <c:simple-property name="propertyToRemove"/> + </c:map-property> + </plugin-configuration> + </server> + + <server name="UpdatedMapWithUpdatedProperty"> + <plugin-configuration> + <c:map-property name="myMap"> + <c:simple-property name="propertyToUpdate" + default="ten" + required="false"/> + </c:map-property> + </plugin-configuration> + </server> </plugin> diff --git a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml index d090e76..4c61512 100644 --- a/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml +++ b/modules/enterprise/server/jar/src/test/resources/org/rhq/enterprise/server/configuration/metadata/configuration_metadata_manager_bean_test_v2.xml @@ -42,4 +42,40 @@ </c:group> </plugin-configuration> </server> + + <server name="UpdatedPropertyList"> + <plugin-configuration> + <c:list-property name="myList" + displayName="My Test List" + readOnly="false" + description="Update Property List Test" + required="true" + min="1" + max="5"> + <c:map-property name="myMap"> + <c:simple-property name="myListMember" + type="double" + default="3.14" + description="PI"/> + </c:map-property> + </c:list-property> + </plugin-configuration> + </server> + + <server name="UpdatedMapWithRemovedProperty"> + <plugin-configuration> + <c:map-property name="myMap"/> + </plugin-configuration> + </server> + + <server name="UpdatedMapWithUpdatedProperty"> + <plugin-configuration> + <c:map-property name="myMap"> + <c:simple-property name="propertyToUpdate" + type="integer" + default="10" + required="true"/> + </c:map-property> + </plugin-configuration> + </server> </plugin>
commit 51ddbfc1c712a4e7cad1812007e77ef17de3e3ba Author: John Mazzitelli mazz@redhat.com Date: Mon Oct 4 15:25:22 2010 -0400
implement the new alert-subject server plugin notification editor. this needs to be tested to make sure the sender still works. but the notification configuration is consistent with how it was before so it should work
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java index 4e9418c..af0882f 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SubjectCriteria.java @@ -22,10 +22,13 @@ */ package org.rhq.core.domain.criteria;
+import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType;
import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.util.CriteriaUtils; import org.rhq.core.domain.util.PageOrdering;
/** @@ -45,7 +48,8 @@ public class SubjectCriteria extends Criteria { private String filterPhoneNumber; private String filterDepartment; private Boolean filterFactive; - private Integer filterRoleId; + private Integer filterRoleId; // needs overrides + private List<Integer> filterIds; // needs overrides
private boolean fetchConfiguration; private boolean fetchRoles; @@ -64,6 +68,8 @@ public class SubjectCriteria extends Criteria { + " FROM Subject innerSubject " // + " JOIN innerSubject.roles innerRole " // + " WHERE innerRole.id = ? )"); + + filterOverrides.put("ids", "id IN ( ? )"); }
@Override @@ -111,6 +117,10 @@ public class SubjectCriteria extends Criteria { this.filterRoleId = filterRoleId; }
+ public void addFilterIds(Integer... filterIds) { + this.filterIds = CriteriaUtils.getListIgnoringNulls(filterIds); + } + public void fetchConfiguration(boolean fetchConfiguration) { this.fetchConfiguration = fetchConfiguration; } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java index 5b8b0b4..0dabe26 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractNotificationSenderForm.java @@ -99,4 +99,6 @@ public abstract class AbstractNotificationSenderForm extends LocatableVLayout { public void setExtraConfiguration(Configuration extraConfiguration) { this.extraConfiguration = extraConfiguration; } + + public abstract boolean validate(); } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java index 390357c..7d8745d 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewNotificationEditor.java @@ -147,8 +147,12 @@ public class NewNotificationEditor extends LocatableDynamicForm { @Override public void onClick(ClickEvent event) { if (validate(false)) { - saveNewNotification(); - closeFunction.run(); + AbstractNotificationSenderForm senderForm = (AbstractNotificationSenderForm) senderCanvasItem + .getCanvas(); + if (senderForm.validate()) { + saveNewNotification(); + closeFunction.run(); + } } } }); @@ -214,7 +218,7 @@ public class NewNotificationEditor extends LocatableDynamicForm { // For those that want to write their own custom alert plugins, you are restricted to // using configuration definitions as the only way to configure the sender. if ("System Users".equals(sender)) { - newCanvas = null; // TODO + newCanvas = new SystemUsersNotificationSenderForm(newLocatorId, notificationToEdit, sender); } else if ("System Roles".equals(sender)) { newCanvas = null; // TODO } else if ("Resource Operations".equals(sender)) { diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java index 4a16380..65ddcd9 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SimpleNotificationSenderForm.java @@ -41,6 +41,8 @@ import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; */ public class SimpleNotificationSenderForm extends AbstractNotificationSenderForm {
+ private ConfigurationEditor configEditor; + public SimpleNotificationSenderForm(String locatorId, AlertNotification notif, String sender) { super(locatorId, notif, sender); } @@ -53,10 +55,10 @@ public class SimpleNotificationSenderForm extends AbstractNotificationSenderForm new AsyncCallback<ConfigurationDefinition>() { @Override public void onSuccess(ConfigurationDefinition configDef) { - ConfigurationEditor configEditor = new ConfigurationEditor(extendLocatorId("configEditor"), - configDef, getConfiguration()); - configEditor.setHeight(500); - configEditor.setWidth(500); + configEditor = new ConfigurationEditor(extendLocatorId("configEditor"), configDef, + getConfiguration()); + configEditor.setHeight(400); + configEditor.setWidth(600); addMember(configEditor); markForRedraw(); } @@ -72,4 +74,13 @@ public class SimpleNotificationSenderForm extends AbstractNotificationSenderForm } }); } + + @Override + public boolean validate() { + if (configEditor != null) { + return configEditor.validate(); + } + return true; + } + } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java new file mode 100644 index 0000000..cdbaedf --- /dev/null +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/SystemUsersNotificationSenderForm.java @@ -0,0 +1,203 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-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, version 2, as + * published by the Free Software Foundation, and/or the GNU Lesser + * General Public License, version 2.1, also as published by the Free + * Software Foundation. + * + * 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 and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser General Public License along with this program; + * if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.rhq.enterprise.gui.coregui.client.alert.definitions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.smartgwt.client.data.Criteria; +import com.smartgwt.client.widgets.form.DynamicForm; +import com.smartgwt.client.widgets.grid.ListGridRecord; + +import org.rhq.core.domain.alert.notification.AlertNotification; +import org.rhq.core.domain.auth.Subject; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.criteria.SubjectCriteria; +import org.rhq.core.domain.util.PageList; +import org.rhq.enterprise.gui.coregui.client.CoreGUI; +import org.rhq.enterprise.gui.coregui.client.admin.users.UsersDataSource; +import org.rhq.enterprise.gui.coregui.client.components.selector.AbstractSelector; +import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; +import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource; + +/** + * This notification form will be used for the System Users sender. This form lets + * you pick users that the sender will send notifications to. + * + * @author John Mazzitelli + */ +public class SystemUsersNotificationSenderForm extends AbstractNotificationSenderForm { + + // the alert configuration property name where the IDs are stored in |-separated form + private static final String PROPNAME = "subjectId"; + + private SubjectSelector selector; + + public SystemUsersNotificationSenderForm(String locatorId, AlertNotification notif, String sender) { + super(locatorId, notif, sender); + } + + @Override + protected void onInit() { + super.onInit(); + + String subjectIds = getConfiguration().getSimpleValue(PROPNAME, ""); // we know the subject plugin defines this + if (subjectIds != null && subjectIds.length() > 0) { + try { + List<Integer> ids = unfence(subjectIds, Integer.class); + SubjectCriteria criteria = new SubjectCriteria(); + criteria.addFilterIds(ids.toArray(new Integer[ids.size()])); + GWTServiceLookup.getSubjectService().findSubjectsByCriteria(criteria, + new AsyncCallback<PageList<Subject>>() { + @Override + public void onSuccess(PageList<Subject> result) { + createNewSelector(result); + } + + @Override + public void onFailure(Throwable caught) { + CoreGUI.getErrorHandler().handleError("Cannot determine current users - starting empty", + caught); + createNewSelector(null); + } + }); + } catch (Exception e) { + CoreGUI.getErrorHandler().handleError("Cannot use current users - starting empty", e); + createNewSelector(null); + } + } else { + createNewSelector(null); + } + } + + private void createNewSelector(Collection<Subject> preselectedSubjects) { + String selectorLocatorId = extendLocatorId("userSelector"); + selector = new SubjectSelector(selectorLocatorId, preselectedSubjects); + selector.setWidth(400); + selector.setHeight(300); + addMember(selector); + markForRedraw(); + } + + @Override + public boolean validate() { + if (selector != null) { + try { + HashSet<Integer> selectedIds = selector.getSelection(); + String newPropValue = fence(selectedIds); + getConfiguration().put(new PropertySimple(PROPNAME, newPropValue)); + return true; + } catch (Exception e) { + CoreGUI.getErrorHandler().handleError("Cannot save the selected users", e); + return false; + } + } + return true; + } + + @SuppressWarnings("unchecked") + private <T> List<T> unfence(String fencedData, Class<T> type) { + String delimiter = "\|"; + String[] elements = fencedData.split(delimiter); + List<T> results = new ArrayList<T>(elements.length); + + if (Integer.class.equals(type)) { + for (String next : elements) { + if (next.length() != 0) { + results.add((T) Integer.valueOf(next)); + } + } + } else if (String.class.equals(type)) { + for (String next : elements) { + if (next.length() != 0) { + results.add((T) next); + } + } + } else { + throw new IllegalArgumentException("No support for unfencing data of type " + type); + } + return results; + } + + /** + * Takes the list of elements e1, e2, e3 and fences + * them with '|' delimiters such that the result looks + * like "|e1|e2|e3|" + */ + private String fence(Collection<?> elements) { + if (elements.size() == 0) { + return ""; + } + StringBuilder builder = new StringBuilder(); + builder.append('|'); + for (Object next : elements) { + builder.append(String.valueOf(next)).append('|'); + } + return builder.toString(); + } + + private class SubjectSelector extends AbstractSelector<Subject> { + + public SubjectSelector(String id, Collection<Subject> subjects) { + super(id); + if (subjects != null) { + ListGridRecord[] data = (new UsersDataSource()).buildRecords(subjects); + setAssigned(data); + } + } + + @Override + protected RPCDataSource<Subject> getDataSource() { + return new SelectedSubjectsDataSource(); + } + + @Override + protected DynamicForm getAvailableFilterForm() { + return null; // No Filters Currently + } + + @Override + protected Criteria getLatestCriteria(DynamicForm availableFilterForm) { + return null; // No Filters Currently + } + + public class SelectedSubjectsDataSource extends UsersDataSource { + + @Override + public ListGridRecord[] buildRecords(Collection<Subject> subjects) { + ListGridRecord[] records = super.buildRecords(subjects); + for (ListGridRecord record : records) { + if (selection.contains(record.getAttributeAsInt("id"))) { + record.setEnabled(false); + } + } + return records; + } + } + + } +} diff --git a/modules/enterprise/server/plugins/alert-subject/pom.xml b/modules/enterprise/server/plugins/alert-subject/pom.xml index 09f2ddc..03e4631 100644 --- a/modules/enterprise/server/plugins/alert-subject/pom.xml +++ b/modules/enterprise/server/plugins/alert-subject/pom.xml @@ -23,31 +23,10 @@
<properties> <scm.module.path>modules/enterprise/server/plugins/alert-subject/</scm.module.path> - <seam.version>2.1.0.SP1</seam.version> </properties>
<dependencies>
- <dependency> - <groupId>org.jboss.seam</groupId> - <artifactId>jboss-seam</artifactId> - <version>${seam.version}</version> - <exclusions> - <exclusion> - <groupId>xml-apis</groupId> - <artifactId>xml-apis</artifactId> - </exclusion> - </exclusions> - </dependency> - - - <dependency> - <groupId>jboss.jboss-embeddable-ejb3</groupId> - <artifactId>jboss-ejb3-all</artifactId> - <version>1.0.0.Alpha9</version> - <scope>compile</scope> - </dependency> - </dependencies>
<build> diff --git a/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsBackingBean.java b/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsBackingBean.java deleted file mode 100644 index b98bb1b..0000000 --- a/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsBackingBean.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2005-2009 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.server.plugins.alertSubject; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.rhq.core.domain.auth.Subject; -import org.rhq.core.domain.configuration.PropertySimple; -import org.rhq.core.domain.util.PageControl; -import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; -import org.rhq.enterprise.server.plugin.pc.alert.CustomAlertSenderBackingBean; -import org.rhq.enterprise.server.util.LookupUtil; - -/** - * Backing Bean for the subjects sender alert sender plugin custom UI - * @author Joseph Marques - */ -public class SubjectsBackingBean extends CustomAlertSenderBackingBean { - - private Map<String, String> available; - private List<String> currentSubjects; - private static final String SUBJECT_ID = "subjectId"; - - @Override - public void loadView() { - // get available/all subjects - List<Subject> allSubjects = LookupUtil.getSubjectManager().findAllSubjects(new PageControl()); - available = new HashMap<String, String>(); - for (Subject subject : allSubjects) { - String subjectId = String.valueOf(subject.getId()); - available.put(subject.getName(), subjectId); - } - - // get current subjects - String subjectString = alertParameters.getSimpleValue(SUBJECT_ID, ""); - currentSubjects = AlertSender.unfence(subjectString, String.class); - } - - @Override - public void saveView() { - String subjectIds = AlertSender.fence(currentSubjects); - - PropertySimple p = alertParameters.getSimple(SUBJECT_ID); - if (p == null) { - p = new PropertySimple(SUBJECT_ID, subjectIds); - alertParameters.put(p); - } else { - p.setStringValue(subjectIds); - } - - alertParameters = persistConfiguration(alertParameters); - } - - public List<String> getCurrentSubjects() { - return currentSubjects; - } - - public void setCurrentSubjects(List<String> currentSubjects) { - this.currentSubjects = currentSubjects; - } - - public Map<String, String> getAvailableSubjectsMap() { - return available; - } - -} diff --git a/modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml index 6260aa4..277df97 100644 --- a/modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml +++ b/modules/enterprise/server/plugins/alert-subject/src/main/resources/META-INF/rhq-serverplugin.xml @@ -15,21 +15,13 @@ Used to send notifications to registered users in the system. </serverplugin:help>
- <!-- startup & tear down listener, + scheduled jobs - <serverplugin:plugin-component class="Foo" /> - --> - - - <!-- How does this sender show up in drop downs etc --> <short-name>System Users</short-name>
<!-- Class that does the actual sending --> <plugin-class>SubjectsSender</plugin-class>
- <custom-ui> - <ui-snippet-name>subjects.xhtml</ui-snippet-name> - <backing-bean-class>SubjectsBackingBean</backing-bean-class> - <backing-bean-name>subjectsBean</backing-bean-name> - </custom-ui> + <alert-configuration> + <c:simple-property name="subjectId" type="string" required="true" description="The subjects (ids are |-separated) to be notified"/> + </alert-configuration> </alert-plugin> \ No newline at end of file diff --git a/modules/enterprise/server/plugins/alert-subject/src/main/resources/subjects.xhtml b/modules/enterprise/server/plugins/alert-subject/src/main/resources/subjects.xhtml deleted file mode 100644 index 39d86e8..0000000 --- a/modules/enterprise/server/plugins/alert-subject/src/main/resources/subjects.xhtml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:c="http://java.sun.com/jstl/core" - xmlns:a4j="https://richfaces.org/a4j" - xmlns:rich="http://richfaces.ajax4jsf.org/rich%22%3E - -<body> - <rich:pickList fastMoveControlsVisible="false" - sourceListWidth="200px" - targetListWidth="200px" - copyControlLabel="Add Subjects" - removeControlLabel="Remove Subjects" - value="#{subjectsBean.currentSubjects}"> - <f:selectItems value="#{subjectsBean.availableSubjectsMap}" /> - </rich:pickList> -</body> - -</html> \ No newline at end of file
commit 98ab21b9a9348520b30fae149d67d39af7553373 Author: Lukas Krejci lkrejci@redhat.com Date: Mon Oct 4 18:58:14 2010 +0200
Getting the InventoryManager.handleReport(InventoryReport) inline with the version in master, updating the upgrade tests to accommodate for the changed behavior.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java index ec40b0c..c5004dd 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java @@ -932,30 +932,16 @@ public class InventoryManager extends AgentService implements ContainerService, }
/** - * @see #handleReport(InventoryReport, boolean) - * @param report - * @return - */ - public boolean handleReport(InventoryReport report) { - return handleReport(report, false); - } - - /** * Send an inventory report to the Server. * * @param report the inventory report to be sent - * @param forceServerRoundtrip whether to report to the server even if there are no resources to report. * @return true if sending the report to the Server succeeded, or false otherwise */ - public boolean handleReport(InventoryReport report, boolean forceServerRoundtrip) { + public boolean handleReport(InventoryReport report) { if (!configuration.isInsideAgent()) { return true; }
- if (report.getAddedRoots().isEmpty() && !forceServerRoundtrip) { - return true; // nothing to do - } - ResourceSyncInfo syncInfo; try { String reportType = (report.isRuntimeReport()) ? "runtime" : "server"; @@ -2659,7 +2645,7 @@ public class InventoryManager extends AgentService implements ContainerService,
log.debug("Executing resource upgrade.");
- boolean syncResult = handleReport(new InventoryReport(getAgent()), true); + boolean syncResult = handleReport(new InventoryReport(getAgent())); if (!syncResult) { log.warn("Resource upgrade failed to sync up the inventory with the server."); return; diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java index ebb73be..ab1cd2b 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeFailureHandlingTest.java @@ -342,10 +342,6 @@ public class ResourceUpgradeFailureHandlingTest extends ResourceUpgradeTestBase expectations.allowing(getCurrentDiscoveryServerService()).upgradeResources( expectations.with(Expectations.any(Set.class))); expectations.will(getCurrentServerSideInventory().upgradeResources()); - - expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources( - expectations.with(Expectations.any(Set.class))); - } catch (InvalidInventoryReportException e) { //this is not going to happen because we're mocking the invocation } diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java index 8b966c3..e2a8a84 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTest.java @@ -93,7 +93,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase { { defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport( + allowing(getCurrentDiscoveryServerService()).mergeInventoryReport( with(any(InventoryReport.class))); will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -144,7 +144,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase { { defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport( + allowing(getCurrentDiscoveryServerService()).mergeInventoryReport( with(any(InventoryReport.class))); will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -197,7 +197,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase {
//the rest of the inventory merges are executed by discoveries, so let's import the //discovered stuff into the server-side inventory. - between(1, 3).of(getCurrentDiscoveryServerService()).mergeInventoryReport( + allowing(getCurrentDiscoveryServerService()).mergeInventoryReport( with(any(InventoryReport.class))); will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -242,7 +242,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase { { defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport( + allowing(getCurrentDiscoveryServerService()).mergeInventoryReport( with(any(InventoryReport.class))); will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
@@ -276,7 +276,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase { { defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport( + allowing(getCurrentDiscoveryServerService()).mergeInventoryReport( with(any(InventoryReport.class))); will(getCurrentServerSideInventory().mergeInventoryReport(requiredInventoryStatus)); } @@ -317,7 +317,7 @@ public class ResourceUpgradeTest extends ResourceUpgradeTestBase { { defineDefaultExpectations(this);
- between(1, 4).of(getCurrentDiscoveryServerService()).mergeInventoryReport( + allowing(getCurrentDiscoveryServerService()).mergeInventoryReport( with(any(InventoryReport.class))); will(getCurrentServerSideInventory().mergeInventoryReport(InventoryStatus.COMMITTED));
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java index 0aefafd..c299cce 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/ResourceUpgradeTestBase.java @@ -402,6 +402,9 @@ public abstract class ResourceUpgradeTestBase { expectations.allowing(getCurrentDiscoveryServerService()).getResources( expectations.with(Expectations.any(Set.class)), expectations.with(Expectations.any(boolean.class))); expectations.will(getCurrentServerSideInventory().getResources()); + + expectations.allowing(getCurrentDiscoveryServerService()).postProcessNewlyCommittedResources( + expectations.with(Expectations.any(Set.class))); }
protected void cleanDataDir() throws IOException {
rhq-commits@lists.fedorahosted.org