001: package org.jivesoftware.openfire.privacy;
002:
003: import org.dom4j.Element;
004: import org.jivesoftware.util.cache.Cache;
005: import org.jivesoftware.util.cache.CacheFactory;
006:
007: import java.util.List;
008: import java.util.concurrent.CopyOnWriteArrayList;
009:
010: /**
011: * A Privacy list manager creates, gets, updates and removes privacy lists. Loaded lists
012: * are kept in memory using a cache that will keep them at most for 6 hours.
013: *
014: * @author Gaston Dombiak
015: */
016: public class PrivacyListManager {
017:
018: private static final PrivacyListManager instance = new PrivacyListManager();
019: private static Cache<String, PrivacyList> listsCache;
020:
021: private PrivacyListProvider provider = new PrivacyListProvider();
022:
023: private List<PrivacyListEventListener> listeners = new CopyOnWriteArrayList<PrivacyListEventListener>();
024:
025: static {
026: PrivacyListEventListener eventListener = new PrivacyListEventListener() {
027: public void privacyListCreated(PrivacyList list) {
028: // Do nothing
029: }
030:
031: public void privacyListDeleting(String listName) {
032: // Do nothing
033: }
034:
035: public void privacyListModified(PrivacyList list) {
036: // Set object again in cache. This is done so that other cluster nodes
037: // get refreshed with latest version of the object
038: listsCache.put(getCacheKey(list.getUserJID().getNode(),
039: list.getName()), list);
040: }
041: };
042: instance.addListener(eventListener);
043: }
044:
045: /**
046: * Returns the unique instance of this class.
047: *
048: * @return the unique instance of this class.
049: */
050: public static PrivacyListManager getInstance() {
051: return instance;
052: }
053:
054: private PrivacyListManager() {
055: // Create the cache of privacy lists
056: String cacheName = "Privacy Lists";
057: listsCache = CacheFactory.createCache(cacheName);
058: }
059:
060: /**
061: * Creates a new privacy list for the specified user.
062: *
063: * @param username the username of the list owner.
064: * @param listName the name of the new privacy list.
065: * @param listElement the XML that specifies the list and its items.
066: * @return the newly created PrivacyList.
067: */
068: public PrivacyList createPrivacyList(String username,
069: String listName, Element listElement) {
070: // Create new list
071: PrivacyList list = new PrivacyList(username, listName, false,
072: listElement);
073: // Add new list to cache
074: listsCache.put(getCacheKey(username, listName), list);
075: // Save new list to database
076: provider.createPrivacyList(username, list);
077: // Trigger event that a new privacy list has been created
078: for (PrivacyListEventListener listener : listeners) {
079: listener.privacyListCreated(list);
080: }
081: return list;
082: }
083:
084: /**
085: * Deletes an existing privacy list of a user. If the privacy list being deleted was
086: * the default list then the user will end up with no default list. Therefore, the user
087: * will have to set a new default list.
088: *
089: * @param username the username of the list owner.
090: * @param listName the name of the list being deleted.
091: */
092: public void deletePrivacyList(String username, String listName) {
093: // Trigger event that a privacy list is being deleted
094: for (PrivacyListEventListener listener : listeners) {
095: listener.privacyListDeleting(listName);
096: }
097: // Remove the list from the cache
098: listsCache.remove(getCacheKey(username, listName));
099: // Delete the privacy list from the DB
100: provider.deletePrivacyList(username, listName);
101: // Check if deleted list was the default list
102: PrivacyList defaultList = listsCache
103: .get(getDefaultCacheKey(username));
104: if (defaultList != null
105: && listName.equals(defaultList.getName())) {
106: listsCache.remove(getDefaultCacheKey(username));
107: }
108: }
109:
110: /**
111: * Deletes all privacy lists of a user. This may be necessary when a user is being
112: * deleted from the system.
113: *
114: * @param username the username of the list owner.
115: */
116: public void deletePrivacyLists(String username) {
117: for (String listName : provider.getPrivacyLists(username)
118: .keySet()) {
119: // Remove the list from the cache
120: listsCache.remove(getCacheKey(username, listName));
121: // Trigger event that a privacy list is being deleted
122: for (PrivacyListEventListener listener : listeners) {
123: listener.privacyListDeleting(listName);
124: }
125: }
126: // Delete user privacy lists from the DB
127: provider.deletePrivacyLists(username);
128: }
129:
130: /**
131: * Returns the default privacy list of the specified user or <tt>null</tt> if
132: * none was found.
133: *
134: * @param username the name of the user to get his default list.
135: * @return the default privacy list of the specified user or <tt>null</tt> if
136: * none was found.
137: */
138: public PrivacyList getDefaultPrivacyList(String username) {
139: // Check if we have the default list in the cache
140: String cacheKey = getDefaultCacheKey(username);
141: PrivacyList list = listsCache.get(cacheKey);
142: if (list == null) {
143: synchronized (username.intern()) {
144: list = listsCache.get(cacheKey);
145: if (list == null) {
146: // Load default list from the database
147: list = provider.loadDefaultPrivacyList(username);
148: if (list != null) {
149: listsCache.put(cacheKey, list);
150: }
151: }
152: }
153: }
154: return list;
155: }
156:
157: /**
158: * Returns a specific privacy list of the specified user or <tt>null</tt> if
159: * none was found.
160: *
161: * @param username the name of the user to get his privacy list.
162: * @param listName the name of the list to get.
163: * @return a privacy list of the specified user or <tt>null</tt> if
164: * none was found.
165: */
166: public PrivacyList getPrivacyList(String username, String listName) {
167: // Check if we have a list in the cache
168: String cacheKey = getCacheKey(username, listName);
169: PrivacyList list = listsCache.get(cacheKey);
170: if (list == null) {
171: // Load the list from the database
172: list = provider.loadPrivacyList(username, listName);
173: if (list != null) {
174: listsCache.put(cacheKey, list);
175: }
176: }
177: return list;
178: }
179:
180: /**
181: * Sets a given privacy list as the new default list of the user.
182: *
183: * @param username the name of the user that is setting a new default list.
184: * @param newDefault the new default privacy list.
185: * @param oldDefault the previous privacy list or <tt>null</tt> if no default list existed.
186: */
187: public void changeDefaultList(String username,
188: PrivacyList newDefault, PrivacyList oldDefault) {
189: // TODO Analyze concurrency issues when other resource may log in while doing this change
190: if (oldDefault != null) {
191: // Update old default list to become just another list
192: oldDefault.setDefaultList(false);
193: provider.updatePrivacyList(username, oldDefault);
194: }
195: // Update new list to become the default
196: newDefault.setDefaultList(true);
197: // Set new default list in the cache
198: listsCache.put(getDefaultCacheKey(username), newDefault);
199: // Update both lists in the database
200: provider.updatePrivacyList(username, newDefault);
201: }
202:
203: /**
204: * Registers a listener to receive events when a privacy list is created, updated or deleted.
205: *
206: * @param listener the listener.
207: */
208: public void addListener(PrivacyListEventListener listener) {
209: if (listener == null) {
210: throw new NullPointerException();
211: }
212: listeners.add(listener);
213: }
214:
215: /**
216: * Unregisters a listener to receive events.
217: *
218: * @param listener the listener.
219: */
220: public void removeListener(PrivacyListEventListener listener) {
221: listeners.remove(listener);
222: }
223:
224: /**
225: * Returns the key to use to locate a privacy list in the cache.
226: */
227: private static String getCacheKey(String username, String listName) {
228: return username + listName;
229: }
230:
231: /**
232: * Returns the key to use to locate default privacy lists in the cache.
233: */
234: private static String getDefaultCacheKey(String username) {
235: return getCacheKey(username, "__d_e_f_a_u_l_t__");
236: }
237:
238: void dispatchModifiedEvent(PrivacyList privacyList) {
239: // Trigger event that a privacy list has been modified
240: for (PrivacyListEventListener listener : listeners) {
241: listener.privacyListModified(privacyList);
242: }
243: }
244: }
|