KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > jforum > repository > TopicRepository


1 /*
2  * Copyright (c) Rafael Steil
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms,
6  * with or without modification, are permitted provided
7  * that the following conditions are met:
8  *
9  * 1) Redistributions of source code must retain the above
10  * copyright notice, this list of conditions and the
11  * following disclaimer.
12  * 2) Redistributions in binary form must reproduce the
13  * above copyright notice, this list of conditions and
14  * the following disclaimer in the documentation and/or
15  * other materials provided with the distribution.
16  * 3) Neither the name of "Rafael Steil" nor
17  * the names of its contributors may be used to endorse
18  * or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
22  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
27  * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
32  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
34  * IN CONTRACT, STRICT LIABILITY, OR TORT
35  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
37  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
38  *
39  * This file creation date: 05/04/2004 - 20:11:44
40  * The JForum Project
41  * http://www.jforum.net
42  */

43 package net.jforum.repository;
44
45 import java.util.ArrayList JavaDoc;
46 import java.util.HashMap JavaDoc;
47 import java.util.Iterator JavaDoc;
48 import java.util.LinkedList JavaDoc;
49 import java.util.List JavaDoc;
50 import java.util.Map JavaDoc;
51
52 import net.jforum.cache.CacheEngine;
53 import net.jforum.cache.Cacheable;
54 import net.jforum.dao.DataAccessDriver;
55 import net.jforum.dao.TopicDAO;
56 import net.jforum.entities.Topic;
57 import net.jforum.util.preferences.ConfigKeys;
58 import net.jforum.util.preferences.SystemGlobals;
59
60 /**
61  * Repository for the last n topics for each forum.
62  *
63  * @author Rafael Steil
64  * @author James Yong
65  * @version $Id: TopicRepository.java,v 1.25 2006/01/16 20:13:56 rafaelsteil Exp $
66  */

67 public class TopicRepository implements Cacheable
68 {
69     private static int maxItems = SystemGlobals.getIntValue(ConfigKeys.TOPICS_PER_PAGE);
70     
71     private static final String JavaDoc FQN = "topics";
72     private static final String JavaDoc RECENT = "recent";
73     private static final String JavaDoc FQN_FORUM = FQN + "/byforum";
74     private static final String JavaDoc RELATION = "relation";
75     private static final String JavaDoc FQN_LOADED = FQN + "/loaded";
76     
77     private static CacheEngine cache;
78     
79     /**
80      * @see net.jforum.cache.Cacheable#setCacheEngine(net.jforum.cache.CacheEngine)
81      */

82     public void setCacheEngine(CacheEngine engine)
83     {
84         cache = engine;
85     }
86     
87     public static boolean isLoaded(int forumId)
88     {
89         return "1".equals(cache.get(FQN_LOADED, Integer.toString(forumId)));
90     }
91
92     /**
93      * Add topic to the FIFO stack
94      *
95      * @param topic The topic to add to stack
96      */

97     public synchronized static void pushTopic(Topic topic) throws Exception JavaDoc
98     {
99         if (SystemGlobals.getBoolValue(ConfigKeys.TOPIC_CACHE_ENABLED)) {
100             int limit = SystemGlobals.getIntValue(ConfigKeys.RECENT_TOPICS);
101             
102             LinkedList JavaDoc l = (LinkedList JavaDoc)cache.get(FQN, RECENT);
103             if (l == null || l.size() == 0) {
104                 l = new LinkedList JavaDoc(loadMostRecentTopics());
105             }
106             
107             l.remove(topic);
108             l.addFirst(topic);
109             
110             while (l.size() > limit) {
111                 l.removeLast();
112             }
113             
114             cache.add(FQN, RECENT, l);
115         }
116     }
117
118     /**
119      * Remove topic to the FIFO stack
120      *
121      * @param topic The topic to remove from stack
122      */

123     public synchronized static void popTopic(Topic topic) throws Exception JavaDoc
124     {
125         if (SystemGlobals.getBoolValue(ConfigKeys.TOPIC_CACHE_ENABLED)) {
126             List JavaDoc l = (List JavaDoc)cache.get(FQN, RECENT);
127             
128             if (l == null || l.size() == 0) {
129                 l = new LinkedList JavaDoc(loadMostRecentTopics());
130             }
131             
132             l.remove(topic);
133             cache.add(FQN, RECENT, l);
134         }
135     }
136
137     /**
138      * Get all cached recent topics.
139      *
140      */

141     public static List JavaDoc getRecentTopics() throws Exception JavaDoc
142     {
143         List JavaDoc l = (List JavaDoc)cache.get(FQN, RECENT);
144         
145         if (l == null || l.size() == 0
146                 || !SystemGlobals.getBoolValue(ConfigKeys.TOPIC_CACHE_ENABLED)) {
147             l = loadMostRecentTopics();
148         }
149         
150         return new ArrayList JavaDoc(l);
151     }
152
153     /**
154      * Add recent topics to the cache
155      */

156     public static List JavaDoc loadMostRecentTopics() throws Exception JavaDoc
157     {
158         TopicDAO tm = DataAccessDriver.getInstance().newTopicDAO();
159         int limit = SystemGlobals.getIntValue(ConfigKeys.RECENT_TOPICS);
160         
161         List JavaDoc l = tm.selectRecentTopics(limit);
162         cache.add(FQN, RECENT, new LinkedList JavaDoc(l));
163         
164         return l;
165     }
166     /**
167      * Add topics to the cache
168      *
169      * @param forumId The forum id to which the topics are related
170      * @param topics The topics to add
171      */

172     public static void addAll(int forumId, List JavaDoc topics)
173     {
174         synchronized (FQN_FORUM) {
175             cache.add(FQN_FORUM, Integer.toString(forumId), new LinkedList JavaDoc(topics));
176             
177             Map JavaDoc m = (Map JavaDoc)cache.get(FQN, RELATION);
178             
179             if (m == null) {
180                 m = new HashMap JavaDoc();
181             }
182             
183             Integer JavaDoc fId = new Integer JavaDoc(forumId);
184             
185             for (Iterator JavaDoc iter = topics.iterator(); iter.hasNext(); ) {
186                 Topic t = (Topic)iter.next();
187                 
188                 m.put(new Integer JavaDoc(t.getId()), fId);
189             }
190             
191             cache.add(FQN, RELATION, m);
192             cache.add(FQN_LOADED, Integer.toString(forumId), "1");
193         }
194     }
195     
196     /**
197      * Clears the cache
198      *
199      * @param forumId The forum id to clear the cache
200      */

201     public static void clearCache(int forumId) throws Exception JavaDoc
202     {
203         synchronized (FQN_FORUM) {
204             cache.add(FQN_FORUM, Integer.toString(forumId), new LinkedList JavaDoc());
205             cache.remove(FQN, RELATION);
206         }
207     }
208     
209     /**
210      * Adds a new topic to the cache
211      *
212      * @param topic The topic to add
213      */

214     public static void addTopic(Topic topic)
215     {
216         if (!SystemGlobals.getBoolValue(ConfigKeys.TOPIC_CACHE_ENABLED)) {
217             return;
218         }
219         
220         synchronized (FQN_FORUM) {
221             String JavaDoc forumId = Integer.toString(topic.getForumId());
222             LinkedList JavaDoc list = (LinkedList JavaDoc)cache.get(FQN_FORUM, forumId);
223             
224             if (list == null) {
225                 list = new LinkedList JavaDoc();
226                 list.add(topic);
227             }
228             else {
229                 boolean contains = list.contains(topic);
230                 
231                 if (!contains && list.size() + 1 > maxItems) {
232                     list.removeLast();
233                 }
234                 else if (contains) {
235                     list.remove(topic);
236                 }
237                 
238                 int index = 0;
239                 
240                 for (Iterator JavaDoc iter = list.iterator(); iter.hasNext(); index++) {
241                     Topic current = (Topic)iter.next();
242                     
243                     if (current.getType() == Topic.TYPE_ANNOUNCE) {
244                         if (topic.getType() == Topic.TYPE_ANNOUNCE) {
245                             list.add(index, topic);
246                             break;
247                         }
248
249                         continue;
250                     }
251                     
252                     if (current.getType() == Topic.TYPE_STICKY) {
253                         if (topic.getType() == Topic.TYPE_STICKY) {
254                             list.add(index, topic);
255                             break;
256                         }
257                         
258                         continue;
259                     }
260
261                     list.add(index, topic);
262                     break;
263                 }
264             }
265             
266             cache.add(FQN_FORUM, forumId, list);
267         
268             Map JavaDoc m = (Map JavaDoc)cache.get(FQN, RELATION);
269             
270             if (m == null) {
271                 m = new HashMap JavaDoc();
272             }
273             
274             m.put(new Integer JavaDoc(topic.getId()), new Integer JavaDoc(forumId));
275             
276             cache.add(FQN, RELATION, m);
277         }
278     }
279     
280     /**
281      * Updates a cached topic
282      *
283      * @param topic The topic to update
284      */

285     public static void updateTopic(Topic topic)
286     {
287         synchronized (FQN_FORUM) {
288             String JavaDoc forumId = Integer.toString(topic.getForumId());
289             List JavaDoc l = (List JavaDoc)cache.get(FQN_FORUM, forumId);
290             
291             if (l != null) {
292                 int index = l.indexOf(topic);
293                 
294                 if (index > -1) {
295                     l.set(index, topic);
296                     cache.add(FQN_FORUM, forumId, l);
297                 }
298             }
299         }
300     }
301         
302     /**
303      * Removes a topic from the cache.
304      * @param topic The topic to remove. The object instance should
305      * have at least the topic_id and forum_id fields set
306      */

307     public static void remove(Topic topic)
308     {
309         synchronized (FQN_FORUM) {
310             if (topic.getForumId() == 0) {
311                 throw new IllegalArgumentException JavaDoc("Forum id cannot be empty");
312             }
313             
314             String JavaDoc forumId = Integer.toString(topic.getForumId());
315             List JavaDoc l = (List JavaDoc)cache.get(FQN_FORUM, forumId);
316             
317             if (l != null) {
318                 l.remove(topic);
319                 cache.add(FQN_FORUM, forumId, l);
320                 
321                 // Relation
322
Map JavaDoc m = (Map JavaDoc)cache.get(FQN, RELATION);
323                 
324                 if (m != null) {
325                     m.remove(new Integer JavaDoc(topic.getId()));
326                     cache.add(FQN, RELATION, m);
327                 }
328             }
329         }
330     }
331     
332     /**
333      * Gets a cached topic.
334      *
335      * @param t The topic to try to get from the cache. The instance
336      * passed as argument should have ae least the topicId and forumId set
337      * @return The topic instance, if found, or <code>null</code> otherwise.
338      */

339     public static Topic getTopic(Topic t)
340     {
341         if (t.getForumId() == 0) {
342             Map JavaDoc m = (Map JavaDoc)cache.get(FQN, RELATION);
343             
344             if (m != null) {
345                 Integer JavaDoc forumId = (Integer JavaDoc)m.get(new Integer JavaDoc(t.getId()));
346                 
347                 if (forumId != null) {
348                     t.setForumId(forumId.intValue());
349                 }
350             }
351             
352             if (t.getForumId() == 0) {
353                 return null;
354             }
355         }
356         
357         List JavaDoc l = (List JavaDoc)cache.get(FQN_FORUM, Integer.toString(t.getForumId()));
358         
359         int index = -1;
360         
361         if (l != null) {
362             index = l.indexOf(t);
363         }
364         
365         return (index == -1 ? null : (Topic)l.get(index));
366     }
367     
368     /**
369      * Checks if a topic is cached
370      *
371      * @param topic The topic to verify
372      * @return <code>true</code> if the topic is cached, or <code>false</code> if not.
373      */

374     public static boolean isTopicCached(Topic topic)
375     {
376         return ((List JavaDoc)cache.get(FQN_FORUM, Integer.toString(topic.getForumId()))).contains(topic);
377     }
378     
379     /**
380      * Get all cached topics related to a forum.
381      *
382      * @param forumid The forum id
383      * @return <code>ArrayList</code> with the topics.
384      */

385     public static List JavaDoc getTopics(int forumid)
386     {
387         if (SystemGlobals.getBoolValue(ConfigKeys.TOPIC_CACHE_ENABLED)) {
388             synchronized (FQN_FORUM) {
389                 List JavaDoc returnList = (List JavaDoc)cache.get(FQN_FORUM, Integer.toString(forumid));
390
391                 if (returnList == null) {
392                     return new ArrayList JavaDoc();
393                 }
394                 
395                 return new ArrayList JavaDoc(returnList);
396             }
397         }
398         
399         return new ArrayList JavaDoc();
400     }
401 }
402
Popular Tags