KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > killingar > forum > internal > caches > GroupMembershipsCache


1 /* Copyright 2000-2005 Anders Hovmöller
2  *
3  * The person or persons who have associated their work with
4  * this document (the "Dedicator") hereby dedicate the entire
5  * copyright in the work of authorship identified below (the
6  * "Work") to the public domain.
7  *
8  * Dedicator makes this dedication for the benefit of the
9  * public at large and to the detriment of Dedicator's heirs
10  * and successors. Dedicator intends this dedication to be an
11  * overt act of relinquishment in perpetuity of all present
12  * and future rights under copyright law, whether vested or
13  * contingent, in the Work. Dedicator understands that such
14  * relinquishment of all rights includes the relinquishment of
15  * all rights to enforce (by lawsuit or otherwise) those
16  * copyrights in the Work.
17  *
18  * Dedicator recognizes that, once placed in the public
19  * domain, the Work may be freely reproduced, distributed,
20  * transmitted, used, modified, built upon, or otherwise
21  * exploited by anyone for any purpose, commercial or non-
22  * commercial, and in any way, including by methods that have
23  * not yet been invented or conceived.
24  */

25
26 /**
27  * Interface for an item with an ID
28  */

29 package net.killingar.forum.internal.caches;
30
31 import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap;
32 import it.unimi.dsi.fastutil.longs.LongIterator;
33 import net.killingar.forum.internal.Group;
34 import net.killingar.forum.internal.User;
35 import net.killingar.forum.internal.managers.AbstractManager;
36 import net.killingar.forum.internal.managers.ForumManager;
37
38 import java.sql.*;
39 import java.util.*;
40
41 public class GroupMembershipsCache
42 {
43     protected Timestamp latestUpdate = new Timestamp(0);
44
45   // map of userID to map of groupID to group
46
protected Long2ObjectAVLTreeMap userToGroups = new Long2ObjectAVLTreeMap();
47     // map of groupID to map of userID to user
48
protected Long2ObjectAVLTreeMap groupToUsers = new Long2ObjectAVLTreeMap();
49
50     protected UsersCache usersCache;
51     protected GroupsCache groupsCache;
52
53     public GroupMembershipsCache(UsersCache inUsersCache, GroupsCache inGroupsCache)
54     {
55         usersCache = inUsersCache;
56         groupsCache = inGroupsCache;
57     }
58
59     public void update() throws SQLException
60     {
61         update(false);
62     }
63
64     public synchronized void update(boolean hardUpdate) throws SQLException
65     {
66         if (!hardUpdate && System.currentTimeMillis()-latestUpdate.getTime() < 1500)
67             return;
68
69         Timestamp now = new Timestamp(System.currentTimeMillis()-1001);
70
71         Connection c = null;
72         PreparedStatement statement = null;
73         ResultSet result = null;
74
75         try
76         {
77             c = AbstractManager.getNewConnection();
78             statement = c.prepareStatement("select Parent, User, Deleted from GroupMemberships where LastChanged > ?");
79
80             statement.setTimestamp(1, latestUpdate);
81
82             result = statement.executeQuery();
83             while (result.next())
84             {
85                 long groupKey = result.getLong(1);
86                 long userKey = result.getLong(2);
87                 boolean deleted = result.getBoolean(3);
88
89                 // update caches
90
if (deleted)
91                 {
92                     removeSafe(userToGroups, userKey, groupKey);
93                     removeSafe(groupToUsers, groupKey, userKey);
94                 }
95                 else
96                 {
97                     Long2ObjectAVLTreeMap userEntry = getEntryAlways(userToGroups, userKey);
98                     Long2ObjectAVLTreeMap groupEntry = getEntryAlways(groupToUsers, groupKey);
99
100                     userEntry.put(groupKey, groupsCache.getGroup(groupKey));
101                     groupEntry.put(userKey, usersCache.getUserItem(userKey));
102                 }
103             }
104         }
105         finally { AbstractManager.closeAll(c, statement, result); }
106
107         latestUpdate = now;
108     }
109
110     private synchronized Long2ObjectAVLTreeMap getEntryAlways(Long2ObjectAVLTreeMap map, long key)
111     {
112         Long2ObjectAVLTreeMap entry = (Long2ObjectAVLTreeMap)map.get(key);
113         if (entry == null)
114         {
115             entry = new Long2ObjectAVLTreeMap();
116             map.put(key, entry);
117         }
118
119         return entry;
120     }
121
122     private synchronized void removeSafe(Long2ObjectAVLTreeMap map, long key, long removeKey)
123     {
124         Long2ObjectAVLTreeMap foo = (Long2ObjectAVLTreeMap)map.get(key);
125         if (foo != null)
126             foo.remove(removeKey);
127     }
128
129     public synchronized Group[] getGroupsOfUser(long userID) throws SQLException
130     {
131         Long2ObjectAVLTreeMap foo = (Long2ObjectAVLTreeMap)userToGroups.get(userID);
132
133         if (foo == null)
134             return new Group[0];
135
136         // extract users from foo
137
Group[] r = (Group[])valuesToArray(foo, Group.class);
138
139         return r;
140     }
141
142     public synchronized User[] getUsersInGroup(ForumManager manager, long groupID) throws SQLException
143     {
144         Long2ObjectAVLTreeMap foo = (Long2ObjectAVLTreeMap)groupToUsers.get(groupID);
145
146         if (foo == null)
147             return new User[0];
148
149         // extract users from foo
150
UserItem[] bar = (UserItem[])valuesToArray(foo, UserItem.class);
151
152         User[] r = new User[bar.length];
153         for (int i = 0; i != r.length; i++)
154             r[i] = bar[i].getUser(manager);
155
156         return r;
157     }
158
159     private static Object JavaDoc valuesToArray(Map inMap, Class JavaDoc inClass)
160     {
161         Set s = inMap.entrySet();
162
163         List l = new ArrayList();
164
165         for (Iterator i = s.iterator(); i.hasNext();)
166         {
167             Map.Entry key = (Map.Entry)i.next();
168             if (key.getValue() != null)
169                 l.add(key.getValue());
170         }
171
172         Object JavaDoc[] r = l.toArray((Object JavaDoc[])java.lang.reflect.Array.newInstance(inClass, l.size()));
173         Arrays.sort(r);
174
175         return r;
176     }
177
178     /**
179      * Returns true if two users share a group of the specified type.
180      * If type is null, any type of group will be considered a hit.
181      */

182     public synchronized boolean sharesGroup(long userID1, long userID2, String JavaDoc type) throws SQLException
183     {
184         if (userID1 == userID2)
185             return true;
186
187         update();
188
189         Long2ObjectAVLTreeMap
190             groupsOf1 = (Long2ObjectAVLTreeMap)userToGroups.get(userID1),
191             groupsOf2 = (Long2ObjectAVLTreeMap)userToGroups.get(userID2);
192
193         if (groupsOf1 == null || groupsOf2 == null)
194             return false;
195
196         for (LongIterator i = (LongIterator)groupsOf1.keySet().iterator(); i.hasNext();)
197         {
198             long key = i.nextLong();
199
200             Group g = (Group)groupsOf2.get(key);
201
202             if (g != null)
203             {
204                 if (type == null || type.equalsIgnoreCase(g.getType()))
205                     return true;
206             }
207         }
208
209         return false;
210     }
211
212     public synchronized boolean sharesGroup(long userID1, long userID2) throws SQLException
213     {
214         return sharesGroup(userID1, userID2, null);
215     }
216
217     public synchronized User[] getCommonGroupUsers(ForumManager manager, long userID) throws SQLException
218     {
219         update();
220
221         Long2ObjectAVLTreeMap foo = new Long2ObjectAVLTreeMap();
222
223         Long2ObjectAVLTreeMap groupsOfUser = (Long2ObjectAVLTreeMap)userToGroups.get(userID);
224
225         if (groupsOfUser == null)
226             return new User[0];
227
228         for (LongIterator i = (LongIterator)groupsOfUser.keySet().iterator(); i.hasNext();)
229         {
230             long key = i.nextLong();
231
232             Long2ObjectAVLTreeMap usersOfGroup = (Long2ObjectAVLTreeMap)groupToUsers.get(key);
233
234             for (Iterator j = usersOfGroup.entrySet().iterator(); j.hasNext();)
235             {
236                 Map.Entry entry = (Map.Entry)j.next();
237                 foo.put(entry.getKey(), entry.getValue());
238             }
239         }
240
241         // extract users from foo
242
UserItem[] bar = (UserItem[])valuesToArray(foo, UserItem.class);
243
244         User[] r = new User[bar.length];
245         for (int i = 0; i != r.length; i++)
246             r[i] = bar[i].getUser(manager);
247
248         return r;
249     }
250
251     public synchronized long getUserAccess(long userID) throws SQLException
252     {
253         update();
254
255         long access = 0;
256
257         Long2ObjectAVLTreeMap groupsOfUser = (Long2ObjectAVLTreeMap)userToGroups.get(userID);
258
259         if (groupsOfUser != null)
260         {
261             for (Iterator i = groupsOfUser.entrySet().iterator(); i.hasNext();)
262             {
263                 Map.Entry entry = (Map.Entry)i.next();
264
265                 access |= ((Group)entry.getValue()).getAccess();
266             }
267         }
268         return access;
269     }
270
271     public synchronized boolean isUserInGroup(long userID, long groupID) throws SQLException
272     {
273         update();
274
275         return getEntryAlways(userToGroups, userID).containsKey(groupID);
276     }
277 }
278
Popular Tags