Commit c4633958 authored by Matt Tucker's avatar Matt Tucker Committed by matt

Cleanup of group caching logic.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@5249 b35dd754-fafc-0310-a699-88a17e54d16e
parent 408c0b29
......@@ -80,7 +80,7 @@ public class PluginManager {
public void start() {
executor = new ScheduledThreadPoolExecutor(1);
// See if we're in development mode. If so, check for new plugins once every 5 seconds.
// Otherwise, default to every 30 seconds.
// Otherwise, default to every 20 seconds.
if (Boolean.getBoolean("developmentMode")) {
executor.scheduleWithFixedDelay(pluginMonitor, 1, 5, TimeUnit.SECONDS);
}
......@@ -817,8 +817,10 @@ public class PluginManager {
// Ask the system to clean up references.
System.gc();
}
// Now unzip the plugin.
unzipPlugin(pluginName, jarFile, dir);
// If the delete operation was a success, unzip the plugin.
if (count != 5) {
unzipPlugin(pluginName, jarFile, dir);
}
}
}
......@@ -969,6 +971,7 @@ public class PluginManager {
for (String file : children) {
boolean success = deleteDir(new File(dir, file));
if (!success) {
System.out.println("could not delete: " + new File(dir, file));
return false;
}
}
......
......@@ -261,7 +261,7 @@ public class DefaultGroupProvider implements GroupProvider {
return count;
}
public Collection<Group> getGroups() {
public Collection<String> getGroupNames() {
List<String> groupNames = new ArrayList<String>();
Connection con = null;
PreparedStatement pstmt = null;
......@@ -289,14 +289,10 @@ public class DefaultGroupProvider implements GroupProvider {
} }
catch (Exception e) { Log.error(e); }
}
return new GroupCollection(groupNames.toArray(new String[groupNames.size()]));
return groupNames;
}
public Collection<Group> getGroups(Set<String> groupNames) {
return new GroupCollection(groupNames.toArray(new String[groupNames.size()]));
}
public Collection<Group> getGroups(int startIndex, int numResults) {
public Collection<String> getGroupNames(int startIndex, int numResults) {
List<String> groupNames = new ArrayList<String>();
Connection con = null;
PreparedStatement pstmt = null;
......@@ -327,10 +323,10 @@ public class DefaultGroupProvider implements GroupProvider {
} }
catch (Exception e) { Log.error(e); }
}
return new GroupCollection(groupNames.toArray(new String[groupNames.size()]));
return groupNames;
}
public Collection<Group> getGroups(JID user) {
public Collection<String> getGroupNames(JID user) {
List<String> groupNames = new ArrayList<String>();
Connection con = null;
PreparedStatement pstmt = null;
......@@ -351,15 +347,17 @@ public class DefaultGroupProvider implements GroupProvider {
try {
if (pstmt != null) {
pstmt.close();
} }
}
}
catch (Exception e) { Log.error(e); }
try {
if (con != null) {
con.close();
} }
}
}
catch (Exception e) { Log.error(e); }
}
return new GroupCollection(groupNames.toArray(new String[groupNames.size()]));
return groupNames;
}
public void addMember(String groupName, JID user, boolean administrator) {
......@@ -449,7 +447,7 @@ public class DefaultGroupProvider implements GroupProvider {
return false;
}
public Collection<Group> search(String query) {
public Collection<String> search(String query) {
if (query == null || "".equals(query)) {
return Collections.emptyList();
}
......@@ -483,10 +481,10 @@ public class DefaultGroupProvider implements GroupProvider {
finally {
DbConnectionManager.closeConnection(rs, stmt, con);
}
return new GroupCollection(groupNames.toArray(new String[groupNames.size()]));
return groupNames;
}
public Collection<Group> search(String query, int startIndex, int numResults) {
public Collection<String> search(String query, int startIndex, int numResults) {
if (query == null || "".equals(query)) {
return Collections.emptyList();
}
......@@ -524,7 +522,7 @@ public class DefaultGroupProvider implements GroupProvider {
finally {
DbConnectionManager.closeConnection(rs, stmt, con);
}
return new GroupCollection(groupNames.toArray(new String[groupNames.size()]));
return groupNames;
}
public boolean isSearchSupported() {
......
......@@ -67,6 +67,7 @@ public class Group implements Cacheable {
* @return the name of the groups that are shared groups.
*/
static Set<String> getSharedGroupsNames() {
// TODO: add caching
Set<String> groupNames = new HashSet<String>();
Connection con = null;
PreparedStatement pstmt = null;
......
......@@ -13,6 +13,7 @@ package org.jivesoftware.wildfire.group;
import java.util.AbstractCollection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Collection;
/**
* Provides a view of an array of group names as a Collection of Group objects. If
......@@ -25,6 +26,13 @@ public class GroupCollection extends AbstractCollection {
private String[] elements;
/**
* Constructs a new GroupCollection.
*/
public GroupCollection(Collection<String> collection) {
this.elements = collection.toArray(new String[collection.size()]);
}
/**
* Constructs a new GroupCollection.
*/
......
......@@ -30,10 +30,6 @@ public class GroupManager {
Cache<String, Group> groupCache;
Cache<String, Collection<Group>> userGroupCache;
// Holds the cache key for the global group in the users groups cache
private final String globalGroupKey = "ALL GROUPS";
// Holds the cache key for the shared groups in the users groups cache
private final String sharedGroupsKey = "SHARED GROUPS";
private GroupProvider provider;
private static GroupManager instance = new GroupManager();
......@@ -140,7 +136,7 @@ public class GroupManager {
if (group == null) {
synchronized (name.intern()) {
group = groupCache.get(name);
// If ID wan't found in cache, load it up and put it there.
// If group wan't found in cache, load it up and put it there.
if (group == null) {
group = provider.getGroup(name);
groupCache.put(name, group);
......@@ -179,13 +175,18 @@ public class GroupManager {
JID userJID = XMPPServer.getInstance().createJID(user.getUsername(), null);
for (Group group : getGroups(userJID)) {
if (group.getAdmins().contains(userJID)) {
group.getAdmins().remove(userJID);
if (group.getAdmins().remove(userJID)) {
// Remove the group from cache.
groupCache.remove(group.getName());
}
}
else {
group.getMembers().remove(userJID);
if (group.getMembers().remove(userJID)) {
// Remove the group from cache.
groupCache.remove(group.getName());
}
}
}
userGroupCache.clear();
}
/**
......@@ -194,11 +195,8 @@ public class GroupManager {
* @return the total number of groups.
*/
public int getGroupCount() {
Collection<Group> groups = userGroupCache.get(globalGroupKey);
if(groups == null) {
return provider.getGroupCount();
}
return groups.size();
// TODO: add caching.
return provider.getGroupCount();
}
/**
......@@ -207,16 +205,9 @@ public class GroupManager {
* @return an unmodifiable Collection of all groups.
*/
public Collection<Group> getGroups() {
synchronized (globalGroupKey) {
Collection<Group> groups = userGroupCache.get(globalGroupKey);
if (groups == null) {
groups = provider.getGroups();
// Add to cache and ensure correct identity
groups = cacheAndEnsureIdentity(groups);
userGroupCache.put(globalGroupKey, groups);
}
return groups;
}
// TODO: add caching.
Collection<String> groupNames = provider.getGroupNames();
return new GroupCollection(groupNames);
}
/**
......@@ -225,38 +216,25 @@ public class GroupManager {
* @return an unmodifiable Collection of all shared groups.
*/
public Collection<Group> getSharedGroups() {
synchronized (sharedGroupsKey) {
Collection<Group> groups = userGroupCache.get(sharedGroupsKey);
if (groups == null) {
Set<String> groupsNames = Group.getSharedGroupsNames();
groups = provider.getGroups(groupsNames);
// Add to cache and ensure correct identity
groups = cacheAndEnsureIdentity(groups);
userGroupCache.put(sharedGroupsKey, groups);
}
return groups;
}
Collection<String> groupNames = Group.getSharedGroupsNames();
return new GroupCollection(groupNames);
}
/**
* Returns an iterator for all groups according to a filter.
* <p/>
* This is useful to support
* pagination in a GUI where you may only want to display a certain
* number of results per page. It is possible that the
* number of results returned will be less than that specified by
* numResults if numResults is greater than the number of records left in
* the system to display.
* Returns all groups given a start index and desired number of results. This is
* useful to support pagination in a GUI where you may only want to display a certain
* number of results per page. It is possible that the number of results returned will
* be less than that specified by numResults if numResults is greater than the number
* of records left in the system to display.
*
* @param startIndex start index in results.
* @param numResults number of results to return.
* @return an Iterator for all groups in the specified range.
*/
public Collection<Group> getGroups(int startIndex, int numResults) {
Collection<Group> groups = provider.getGroups(startIndex, numResults);
// Add to cache and ensure correct identity
groups = cacheAndEnsureIdentity(groups);
return groups;
// TODO: add caching
Collection<String> groupNames = provider.getGroupNames(startIndex, numResults);
return new GroupCollection(groupNames);
}
/**
......@@ -276,17 +254,9 @@ public class GroupManager {
* @return all groups that an entity belongs to.
*/
public Collection<Group> getGroups(JID user) {
String userID = user.toString();
synchronized (userID.intern()) {
Collection<Group> groups = userGroupCache.get(userID);
if (groups == null) {
groups = provider.getGroups(user);
// Add to cache and ensure correct identity
groups = cacheAndEnsureIdentity(groups);
userGroupCache.put(userID, groups);
}
return groups;
}
// TODO: add caching
Collection<String> groupNames = provider.getGroupNames(user);
return new GroupCollection(groupNames);
}
/**
......@@ -320,7 +290,8 @@ public class GroupManager {
* @return all groups that match the search.
*/
public Collection<Group> search(String query) {
return provider.search(query);
Collection<String> groupNames = provider.search(query);
return new GroupCollection(groupNames);
}
/**
......@@ -337,7 +308,8 @@ public class GroupManager {
* @return all groups that match the search.
*/
public Collection<Group> search(String query, int startIndex, int numResults) {
return provider.search(query, startIndex, numResults);
Collection<String> groupNames = provider.search(query, startIndex, numResults);
return new GroupCollection(groupNames);
}
/**
......@@ -346,33 +318,7 @@ public class GroupManager {
*
* @return the group provider.
*/
GroupProvider getProvider() {
public GroupProvider getProvider() {
return provider;
}
/**
* Caches groups present in the specified collection that are not already cached and
* ensures correct identity of already cached groups.
*
* @param groups loaded groups from the backend store.
* @return a list containing the correct and valid groups (i.e. ensuring identity).
*/
private Collection<Group> cacheAndEnsureIdentity(Collection<Group> groups) {
Collection<Group> answer = new ArrayList<Group>(groups.size());
for (Group group : groups) {
synchronized (group.getName().intern()) {
Group existingGroup = groupCache.get(group.getName());
if (existingGroup == null) {
// Add loaded group to the cache
groupCache.put(group.getName(), group);
answer.add(group);
}
else {
// Replace loaded group with the cached one to ensure correct identity
answer.add(existingGroup);
}
}
}
return answer;
}
}
\ No newline at end of file
......@@ -14,7 +14,6 @@ package org.jivesoftware.wildfire.group;
import org.xmpp.packet.JID;
import java.util.Collection;
import java.util.Set;
/**
* Provider interface for groups. Users that wish to integrate with
......@@ -98,35 +97,29 @@ public interface GroupProvider {
int getGroupCount();
/**
* Returns the Collection of all groups in the system.
* Returns the Collection of all group names in the system.
*
* @return the Collection of all groups.
*/
Collection<Group> getGroups();
/**
* Returns the Collection of groups for the specified groups names.
*
* @return the Collection with the requested groups.
*/
Collection<Group> getGroups(Set<String> groupNames);
Collection<String> getGroupNames();
/**
* Returns the Collection of all groups in the system.
*
* @param startIndex start index in results.
* @param numResults number of results to return.
* @return the Collection of all groups given the <tt>startIndex</tt> and <tt>numResults</tt>.
* @return the Collection of all group names given the
* <tt>startIndex</tt> and <tt>numResults</tt>.
*/
Collection<Group> getGroups(int startIndex, int numResults);
Collection<String> getGroupNames(int startIndex, int numResults);
/**
* Returns the Collection of Groups that an entity belongs to.
* Returns the Collection of group names that an entity belongs to.
*
* @param user the JID of the entity.
* @return the Collection of groups that the user belongs to.
* @return the Collection of group names that the user belongs to.
*/
Collection<Group> getGroups(JID user);
Collection<String> getGroupNames(JID user);
/**
* Adds an entity to a group (optional operation).
......@@ -171,7 +164,7 @@ public interface GroupProvider {
boolean isReadOnly();
/**
* Returns the groups that match the search. The search is over group names and
* Returns the group names that match a search. The search is over group names and
* implicitly uses wildcard matching (although the exact search semantics are left
* up to each provider implementation). For example, a search for "HR" should match
* the groups "HR", "HR Department", and "The HR People".<p>
......@@ -182,10 +175,10 @@ public interface GroupProvider {
* @param query the search string for group names.
* @return all groups that match the search.
*/
Collection<Group> search(String query);
Collection<String> search(String query);
/**
* Returns the groups that match the search given a start index and desired number of results.
* Returns the group names that match a search given a start index and desired number of results.
* The search is over group names and implicitly uses wildcard matching (although the
* exact search semantics are left up to each provider implementation). For example, a
* search for "HR" should match the groups "HR", "HR Department", and "The HR People".<p>
......@@ -196,7 +189,7 @@ public interface GroupProvider {
* @param query the search string for group names.
* @return all groups that match the search.
*/
Collection<Group> search(String query, int startIndex, int numResults);
Collection<String> search(String query, int startIndex, int numResults);
/**
* Returns true if group searching is supported by the provider.
......
......@@ -227,7 +227,7 @@ public class JDBCGroupProvider implements GroupProvider {
return count;
}
public Collection<Group> getGroups() {
public Collection<String> getGroupNames() {
List<String> groupNames = new ArrayList<String>();
Connection con = null;
PreparedStatement pstmt = null;
......@@ -246,32 +246,10 @@ public class JDBCGroupProvider implements GroupProvider {
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
List<Group> groups = new ArrayList<Group>(groupNames.size());
for (String groupName : groupNames) {
try {
groups.add(getGroup(groupName));
}
catch (GroupNotFoundException e) {
Log.error(e);
}
}
return groups;
}
public Collection<Group> getGroups(Set<String> groupNames) {
List<Group> groups = new ArrayList<Group>(groupNames.size());
for (String groupName : groupNames) {
try {
groups.add(getGroup(groupName));
}
catch (GroupNotFoundException e) {
Log.error(e);
}
}
return groups;
return groupNames;
}
public Collection<Group> getGroups(int start, int num) {
public Collection<String> getGroupNames(int start, int num) {
List<String> groupNames = new ArrayList<String>();
Connection con = null;
PreparedStatement pstmt = null;
......@@ -293,19 +271,10 @@ public class JDBCGroupProvider implements GroupProvider {
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
List<Group> groups = new ArrayList<Group>(groupNames.size());
for (String groupName : groupNames) {
try {
groups.add(getGroup(groupName));
}
catch (GroupNotFoundException e) {
Log.error(e);
}
}
return groups;
return groupNames;
}
public Collection<Group> getGroups(JID user) {
public Collection<String> getGroupNames(JID user) {
List<String> groupNames = new ArrayList<String>();
Connection con = null;
PreparedStatement pstmt = null;
......@@ -325,16 +294,7 @@ public class JDBCGroupProvider implements GroupProvider {
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
List<Group> groups = new ArrayList<Group>(groupNames.size());
for (String groupName : groupNames) {
try {
groups.add(getGroup(groupName));
}
catch (GroupNotFoundException e) {
Log.error(e);
}
}
return groups;
return groupNames;
}
/**
......@@ -360,7 +320,8 @@ public class JDBCGroupProvider implements GroupProvider {
* @throws UnsupportedOperationException when called.
*/
public void updateMember(String groupName, JID user, boolean administrator)
throws UnsupportedOperationException {
throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
}
......@@ -372,7 +333,8 @@ public class JDBCGroupProvider implements GroupProvider {
* @throws UnsupportedOperationException when called.
*/
public void deleteMember(String groupName, JID user)
throws UnsupportedOperationException {
throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
}
......@@ -385,11 +347,11 @@ public class JDBCGroupProvider implements GroupProvider {
return true;
}
public Collection<Group> search(String query) {
public Collection<String> search(String query) {
return Collections.emptyList();
}
public Collection<Group> search(String query, int startIndex, int numResults) {
public Collection<String> search(String query, int startIndex, int numResults) {
return Collections.emptyList();
}
......
......@@ -31,9 +31,6 @@
<!-- Define Administration Bean -->
<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager"/>
<% webManager.init(pageContext); %>
<jsp:useBean id="errors" class="java.util.HashMap"/>
<% // Get parameters
boolean add = request.getParameter("add") != null;
......@@ -50,6 +47,8 @@
String newDescription = ParamUtils.getParameter(request, "newDescription");
boolean groupInfoChanged = ParamUtils.getBooleanParameter(request, "groupChanged", false);
Map<String,String> errors = new HashMap<String,String>();
// Get the presence manager
PresenceManager presenceManager = webManager.getPresenceManager();
UserManager userManager = webManager.getUserManager();
......@@ -98,7 +97,6 @@
}
groupName = newName;
groupInfoChanged = true;
// Get admin list and compare it the admin posted list.
response.sendRedirect("group-edit.jsp?group=" + URLEncoder.encode(groupName, "UTF-8") + "&groupChanged=true");
return;
......@@ -113,8 +111,8 @@
if (update) {
Set<JID> adminIDSet = new HashSet<JID>();
for (int i = 0; i < adminIDs.length; i++) {
JID newAdmin = new JID(adminIDs[i]);
for (String adminID : adminIDs) {
JID newAdmin = new JID(adminID);
adminIDSet.add(newAdmin);
boolean isAlreadyAdmin = group.getAdmins().contains(newAdmin);
if (!isAlreadyAdmin) {
......@@ -122,18 +120,15 @@
group.getAdmins().add(newAdmin);
}
}
Iterator<JID> groupIter = Collections.unmodifiableCollection(group.getAdmins()).iterator();
Collection<JID> admins = Collections.unmodifiableCollection(group.getAdmins());
Set<JID> removeList = new HashSet<JID>();
while (groupIter.hasNext()) {
JID m = (JID) groupIter.next();
if (!adminIDSet.contains(m)) {
removeList.add(m);
for (JID admin : admins) {
if (!adminIDSet.contains(admin)) {
removeList.add(admin);
}
}
Iterator<JID> i = removeList.iterator();
while (i.hasNext()) {
JID m = (JID) i.next();
group.getMembers().add(m);
for (JID member : removeList) {
group.getMembers().add(member);
}
// Get admin list and compare it the admin posted list.
response.sendRedirect("group-edit.jsp?group=" + URLEncoder.encode(groupName, "UTF-8") + "&updatesuccess=true");
......@@ -191,8 +186,8 @@
add = false;
}
else if (delete) {
for (int i = 0; i < deleteMembers.length; i++) {
JID member = new JID(deleteMembers[i]);
for (String deleteMember : deleteMembers) {
JID member = new JID(deleteMember);
group.getMembers().remove(member);
group.getAdmins().remove(member);
}
......@@ -586,7 +581,7 @@
}
%>
</table>
</div>
</form>
<script type="text/javascript">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment