modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LoginView.java
| 8 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java
| 38 +++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java
| 11 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
| 68 +++++++---
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/prefs/SubjectPreferencesCache.java
| 16 ++
5 files changed, 120 insertions(+), 21 deletions(-)
New commits:
commit f125951729ef398cfb32a1365ef059e39273b467
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Mar 29 18:19:01 2012 +0200
[BZ 804303] - Instead of saving the whole set of preferences when changing
the view in the GWT UI, just persist only the prefs that have actually
changed in GWT.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LoginView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LoginView.java
index 514746c..0428671 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LoginView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/LoginView.java
@@ -23,7 +23,9 @@
package org.rhq.enterprise.gui.coregui.client;
import java.util.EnumSet;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import java.util.logging.Logger;
import com.google.gwt.event.dom.client.KeyCodes;
@@ -480,7 +482,11 @@ public class LoginView extends LocatableCanvas {
PropertySimple simple = new PropertySimple("isNewUser", null);
newSubject.getUserConfiguration().put(simple);
}
- GWTServiceLookup.getSubjectService().updateSubject(newSubject, new
AsyncCallback<Subject>() {
+
+ Set<String> prefsChanges = new HashSet<String>();
+ prefsChanges.add("isNewUser");
+
+ GWTServiceLookup.getSubjectService().updateSubjectAndPreferences(newSubject,
prefsChanges, new AsyncCallback<Subject>() {
public void onFailure(Throwable caught) {
Log.error("Failed to register LDAP subject '" +
newSubject.getName() + "' " + caught.getMessage(),
caught);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java
index 8e4640c..8063f20 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/SubjectGWTService.java
@@ -18,6 +18,8 @@
*/
package org.rhq.enterprise.gui.coregui.client.gwt;
+import java.util.Set;
+
import com.google.gwt.user.client.rpc.RemoteService;
import org.rhq.core.domain.auth.Principal;
@@ -89,15 +91,17 @@ public interface SubjectGWTService extends RemoteService {
void logout(int sessionId) throws RuntimeException;
/**
- * Updates an existing subject with new data. This does <b>not</b>
cascade any changes to the roles, but it will save
- * the subject's configuration.
- *
+ * Updates an existing subject with new data. This does <b>not</b>
cascade any changes to the roles and it
+ * will <b>NOT</b> save the subject's preferences (the reason for
that is that the preferences
+ * are still updated both in the old JSF UI as well as in the GWT UI and figuring out
what values
+ * changed requires some more work than simply saving the GWT's view of the
preferences).
+ *
* @param subjectToModify the subject whose data is to be updated (which may or may
not be the same as <code>user</code>)
*
* @return the merged subject, which may or may not be the same instance of
<code>subjectToModify</code>
*/
Subject updateSubject(Subject subjectToModify) throws RuntimeException;
-
+
/**
* Updates an existing subject with new data. This cascades changes to roles and LDAP
roles, so the passed-in
* subject should be fully-fetched (i.e. both roles and LDAP roles should be
fetched).
@@ -110,6 +114,32 @@ public interface SubjectGWTService extends RemoteService {
Subject updateSubject(Subject subjectToModify, String newPassword) throws
RuntimeException;
/**
+ * This will update the preferences of the supplied subject (which might or might not
be the same as the
+ * current user).
+ *
+ * @param subjectToModify the subject to modify the preferences of
+ * @param changedPrefs the set of preference names that are known to have changed -
only the preferences
+ * with these names will be persisted to the database.
+ * @return the subject with the preferences updated to match the persisted state
(which might contain
+ * additional changes - this is because the prefs are still being updated both in the
GWT and JSF UIs).
+ *
+ * @throws RuntimeException
+ */
+ Subject updateSubjectPreferences(Subject subjectToModify, Set<String>
changedPrefs) throws RuntimeException;
+
+ /**
+ * A combination of {@link #updateSubject(Subject)} and {@link
#updateSubjectPreferences(Subject, Set)} methods.
+ * <p>
+ * This method will therefore modify both the subject and the preferences that
changed.
+ *
+ * @param subjectToModify
+ * @param changedPrefs
+ * @return
+ * @throws RuntimeException
+ */
+ Subject updateSubjectAndPreferences(Subject subjectToModify, Set<String>
changedPrefs) throws RuntimeException;
+
+ /**
* Queries subjects using current logged in user.
*
* @param criteria details for the search
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java
index 25fed3a..09279cd 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java
@@ -58,6 +58,8 @@ public class UserPreferences {
private ArrayList<UserPreferenceChangeListener> changeListeners = new
ArrayList<UserPreferenceChangeListener>();
+ private HashSet<String> changedPreferenceKeys = new HashSet<String>();
+
// when these preferences change, they should not trigger a refresh.
private static ArrayList<String> preferencesThatShouldNotCauseRefresh;
static {
@@ -65,7 +67,7 @@ public class UserPreferences {
preferencesThatShouldNotCauseRefresh.add(UserPreferenceNames.RECENT_RESOURCES);
preferencesThatShouldNotCauseRefresh.add(UserPreferenceNames.RECENT_RESOURCE_GROUPS);
}
-
+
public UserPreferences(Subject subject) {
this.subject = subject;
this.userConfiguration = subject.getUserConfiguration();
@@ -269,6 +271,8 @@ public class UserPreferences {
prop.setStringValue(value);
}
+ changedPreferenceKeys.add(name);
+
UserPreferenceChangeEvent event = new AutoPersistAwareChangeEvent(name, value,
oldValue, persistCallback);
for (UserPreferenceChangeListener listener : changeListeners) {
listener.onPreferenceChange(event);
@@ -291,6 +295,8 @@ public class UserPreferences {
listener.onPreferenceRemove(event);
}
}
+
+ changedPreferenceKeys.add(name);
}
public void clearConfiguration() {
@@ -309,7 +315,8 @@ public class UserPreferences {
}
public void store(AsyncCallback<Subject> persistCallback) {
- this.subjectService.updateSubject(this.subject, persistCallback);
+ this.subjectService.updateSubjectPreferences(this.subject, changedPreferenceKeys,
persistCallback);
+ changedPreferenceKeys.clear();
}
public Configuration getConfiguration() {
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
index e175134..97ec22f 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/SubjectGWTServiceImpl.java
@@ -18,7 +18,11 @@
*/
package org.rhq.enterprise.gui.coregui.server.gwt;
+import java.util.Set;
+
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.criteria.SubjectCriteria;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.gwt.SubjectGWTService;
@@ -89,20 +93,7 @@ public class SubjectGWTServiceImpl extends AbstractGWTServiceImpl
implements Sub
}
public Subject updateSubject(Subject subjectToModify) throws RuntimeException {
- try {
- Subject sessionSubject = getSessionSubject();
- Subject modifiedSubject;
- synchronized (subjectLock) {
- modifiedSubject = subjectManager.updateSubject(sessionSubject,
subjectToModify);
- }
- Subject subject = SerialUtility.prepare(modifiedSubject,
"SubjectManager.updateSubject");
- // Clear the prefs for this subject from the user prefs cache that portal-war
uses, in case we just
- // changed any prefs; otherwise the cache would contain stale prefs.
- SubjectPreferencesCache.getInstance().clearConfiguration(subject.getId());
- return subject;
- } catch (Throwable t) {
- throw getExceptionToThrowToClient(t);
- }
+ return updateSubjectAndPreferences(subjectToModify, null, true, false);
}
public Subject updateSubject(Subject subjectToModify, String newPassword) throws
RuntimeException {
@@ -122,6 +113,14 @@ public class SubjectGWTServiceImpl extends AbstractGWTServiceImpl
implements Sub
}
}
+ public Subject updateSubjectPreferences(Subject subjectToModify, Set<String>
changedPrefs) throws RuntimeException {
+ return updateSubjectAndPreferences(subjectToModify, changedPrefs, false, true);
+ }
+
+ public Subject updateSubjectAndPreferences(Subject subjectToModify, Set<String>
changedPrefs) throws RuntimeException {
+ return updateSubjectAndPreferences(subjectToModify, changedPrefs, true, true);
+ }
+
public Subject processSubjectForLdap(Subject subjectToModify, String password) throws
RuntimeException {
//no permissions check as embedded in the SLSB call.
try {
@@ -159,4 +158,45 @@ public class SubjectGWTServiceImpl extends AbstractGWTServiceImpl
implements Sub
throw getExceptionToThrowToClient(t);
}
}
+
+ private Subject updateSubjectAndPreferences(Subject subjectToModify,
Set<String> changedPrefs, boolean updateSubject, boolean updatePrefs) {
+ try {
+ Subject sessionSubject = getSessionSubject();
+ Subject modifiedSubject;
+ synchronized (subjectLock) {
+ if (!updateSubject) {
+ subjectToModify =
subjectManager.getSubjectById(subjectToModify.getId());
+ }
+
+ Configuration persistedPrefs =
SubjectPreferencesCache.getInstance().getPreferences(subjectToModify.getId());
+
+ if (updatePrefs && changedPrefs != null) {
+ Configuration userPrefs = subjectToModify.getUserConfiguration();
+ for(String name : changedPrefs) {
+ Property prop = userPrefs.get(name);
+ if (prop == null) {
+ persistedPrefs.remove(name);
+ } else {
+ persistedPrefs.put(prop);
+ }
+ }
+ }
+
+ subjectToModify.setUserConfiguration(persistedPrefs);
+
+ modifiedSubject = subjectManager.updateSubject(sessionSubject,
subjectToModify);
+
+ if (updatePrefs) {
+ //clear the prefs cache so that JSF UI refreshes it
+
SubjectPreferencesCache.getInstance().clearConfiguration(subjectToModify.getId());
+ }
+ }
+
+ Subject subject = SerialUtility.prepare(modifiedSubject,
"SubjectManager.updateSubjectPW");
+
+ return subject;
+ } catch (Throwable t) {
+ throw getExceptionToThrowToClient(t);
+ }
+ }
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/prefs/SubjectPreferencesCache.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/prefs/SubjectPreferencesCache.java
index 1b23660..d88bd85 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/prefs/SubjectPreferencesCache.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/prefs/SubjectPreferencesCache.java
@@ -114,6 +114,22 @@ public class SubjectPreferencesCache {
}
}
+ /**
+ * @param subjectId the subject to get preferences of
+ * @return the <b>COPY</b> of the configuration object - changes done to
that instance will not be reflected in the persisted
+ * preferences
+ */
+ public synchronized Configuration getPreferences(int subjectId) {
+ load(subjectId);
+
+ Configuration config = subjectPreferences.get(subjectId);
+ if (config == null) {
+ return new Configuration();
+ } else {
+ return config.deepCopy();
+ }
+ }
+
public synchronized void clearConfiguration(int subjectId) {
if (log.isTraceEnabled()) {
log.trace("Removing PreferencesCache For " + subjectId);