GroupManager.java 6.08 KB
Newer Older
Matt Tucker's avatar
Matt Tucker committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
 * Copyright (C) 2004 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.messenger.group;

14
import org.jivesoftware.util.*;
Matt Tucker's avatar
Matt Tucker committed
15
import org.jivesoftware.messenger.user.User;
16
import org.jivesoftware.util.JiveGlobals;
Matt Tucker's avatar
Matt Tucker committed
17
import org.jivesoftware.messenger.event.GroupEventDispatcher;
Matt Tucker's avatar
Matt Tucker committed
18 19

import java.util.Collection;
Matt Tucker's avatar
Matt Tucker committed
20
import java.util.Collections;
Matt Tucker's avatar
Matt Tucker committed
21 22

/**
Matt Tucker's avatar
Matt Tucker committed
23
 * Manages groups.
Matt Tucker's avatar
Matt Tucker committed
24 25 26 27 28 29 30 31 32
 *
 * @see Group
 * @author Matt Tucker
 */
public class GroupManager {

    Cache groupCache;
    private GroupProvider provider;

Matt Tucker's avatar
Matt Tucker committed
33 34 35 36 37 38 39
    private static GroupManager instance = new GroupManager();

    /**
     * Returns a singleton instance of GroupManager.
     *
     * @return a GroupManager instance.
     */
Matt Tucker's avatar
Matt Tucker committed
40
    public static GroupManager getInstance() {
Matt Tucker's avatar
Matt Tucker committed
41
        return instance;
Matt Tucker's avatar
Matt Tucker committed
42 43 44 45 46 47 48 49
    }

    private GroupManager() {
        // Initialize caches.
        CacheManager.initializeCache("group", 128 * 1024);
        CacheManager.initializeCache("group member", 32 * 1024);
        groupCache = CacheManager.getCache("group");
        // Load a group provider.
Matt Tucker's avatar
Matt Tucker committed
50 51
        String className = JiveGlobals.getXMLProperty("provider.group.className",
                "org.jivesoftware.messenger.group.DefaultGroupProvider");
Matt Tucker's avatar
Matt Tucker committed
52 53 54 55 56 57
        try {
            Class c = ClassUtils.forName(className);
            provider = (GroupProvider)c.newInstance();
        }
        catch (Exception e) {
            Log.error("Error loading group provider: " + className, e);
Matt Tucker's avatar
Matt Tucker committed
58
            provider = new DefaultGroupProvider();
Matt Tucker's avatar
Matt Tucker committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
        }
    }

    /**
     * Factory method for creating a new Group. A unique name is the only required field.
     *
     * @param name the new and unique name for the group.
     * @return a new Group.
     * @throws GroupAlreadyExistsException if the group name already exists in the system.
     */
    public Group createGroup(String name) throws GroupAlreadyExistsException {
        synchronized (name.intern()) {
            Group newGroup = null;
            try {
                getGroup(name);
                // The group already exists since now exception, so:
                throw new GroupAlreadyExistsException();
            }
            catch (GroupNotFoundException unfe) {
                // The group doesn't already exist so we can create a new group
                newGroup = provider.createGroup(name);
                groupCache.put(name, newGroup);
Matt Tucker's avatar
Matt Tucker committed
81 82

                // Fire event.
Matt Tucker's avatar
Matt Tucker committed
83 84
                GroupEventDispatcher.dispatchEvent(newGroup,
                        GroupEventDispatcher.EventType.group_created, Collections.emptyMap());
Matt Tucker's avatar
Matt Tucker committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
            }
            return newGroup;
        }
    }

    /**
     * Returns a Group by name.
     *
     * @param name The name of the group to retrieve
     * @return The group corresponding to that name
     * @throws GroupNotFoundException if the group does not exist.
     */
    public Group getGroup(String name) throws GroupNotFoundException {
        Group group = (Group)groupCache.get(name);
        // If ID wan't found in cache, load it up and put it there.
        if (group == null) {
101 102 103 104 105 106 107 108
            synchronized (name.intern()) {
                group = (Group)groupCache.get(name);
                // If ID wan't found in cache, load it up and put it there.
                if (group == null) {
                    group = provider.getGroup(name);
                    groupCache.put(name, group);
                }
            }
Matt Tucker's avatar
Matt Tucker committed
109 110 111 112 113 114 115 116 117 118
        }
        return group;
    }

    /**
     * Deletes a group from the system.
     *
     * @param group the group to delete.
     */
    public void deleteGroup(Group group) {
Matt Tucker's avatar
Matt Tucker committed
119
        // Fire event.
Matt Tucker's avatar
Matt Tucker committed
120 121
        GroupEventDispatcher.dispatchEvent(group, GroupEventDispatcher.EventType.group_deleting,
                Collections.emptyMap());
Matt Tucker's avatar
Matt Tucker committed
122

Matt Tucker's avatar
Matt Tucker committed
123 124 125 126 127
        // Delete the group.
        provider.deleteGroup(group.getName());

        // Expire all relevant caches.
        groupCache.remove(group.getName());
128 129 130
    }

    /**
Matt Tucker's avatar
Matt Tucker committed
131 132 133 134
     * Deletes a user from all the groups where he/she belongs. The most probable cause
     * for this request is that the user has been deleted from the system.
     *
     * TODO: remove this method and use events isntead.
135 136 137 138 139
     *
     * @param user the deleted user from the system.
     */
    public void deleteUser(User user) {
        for (Group group : getGroups(user)) {
140 141
            if (group.getAdmins().contains(user.getUsername())) {
                group.getAdmins().remove(user.getUsername());
142 143
            }
            else {
144
                group.getMembers().remove(user.getUsername());
145 146
            }
        }
Matt Tucker's avatar
Matt Tucker committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
    }

    /**
     * Returns the total number of groups in the system.
     *
     * @return the total number of groups.
     */
    public int getGroupCount() {
        return provider.getGroupCount();
    }

    /**
     * Returns an unmodifiable Collection of all groups in the system.
     *
     * @return an unmodifiable Collection of all groups.
     */
    public Collection<Group> getGroups() {
        return provider.getGroups();
    }

    /**
     * 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.
     *
     * @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) {
        return provider.getGroups(startIndex, numResults);
    }

    /**
     * Returns an iterator for all groups that a user is a member of.
     *
     * @param user the user to get a list of groups for.
     * @return all groups that a user belongs to.
     */
    public Collection<Group> getGroups(User user) {
        return provider.getGroups(user);
    }
}