001: /*
002: * Copyright (c) JForum Team
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms,
006: * with or without modification, are permitted provided
007: * that the following conditions are met:
008: *
009: * 1) Redistributions of source code must retain the above
010: * copyright notice, this list of conditions and the
011: * following disclaimer.
012: * 2) Redistributions in binary form must reproduce the
013: * above copyright notice, this list of conditions and
014: * the following disclaimer in the documentation and/or
015: * other materials provided with the distribution.
016: * 3) Neither the name of "Rafael Steil" nor
017: * the names of its contributors may be used to endorse
018: * or promote products derived from this software without
019: * specific prior written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
022: * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
023: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
024: * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
025: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR
026: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
027: * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
028: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
029: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES
030: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
031: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
032: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
033: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
034: * IN CONTRACT, STRICT LIABILITY, OR TORT
035: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
036: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
037: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
038: *
039: * This file creation date: Apr 23, 2003 / 10:46:05 PM
040: * The JForum Project
041: * http://www.jforum.net
042: */
043: package net.jforum.repository;
044:
045: import java.text.SimpleDateFormat;
046: import java.util.ArrayList;
047: import java.util.Collection;
048: import java.util.HashMap;
049: import java.util.Iterator;
050: import java.util.List;
051: import java.util.Map;
052: import java.util.Set;
053: import java.util.TreeSet;
054:
055: import org.apache.log4j.Logger;
056:
057: import net.jforum.SessionFacade;
058: import net.jforum.cache.CacheEngine;
059: import net.jforum.cache.Cacheable;
060: import net.jforum.dao.CategoryDAO;
061: import net.jforum.dao.ConfigDAO;
062: import net.jforum.dao.DataAccessDriver;
063: import net.jforum.dao.ForumDAO;
064: import net.jforum.dao.UserDAO;
065: import net.jforum.entities.Category;
066: import net.jforum.entities.Config;
067: import net.jforum.entities.Forum;
068: import net.jforum.entities.LastPostInfo;
069: import net.jforum.entities.MostUsersEverOnline;
070: import net.jforum.entities.Post;
071: import net.jforum.entities.Topic;
072: import net.jforum.entities.User;
073: import net.jforum.exceptions.CategoryNotFoundException;
074: import net.jforum.exceptions.DatabaseException;
075: import net.jforum.security.PermissionControl;
076: import net.jforum.security.SecurityConstants;
077: import net.jforum.util.CategoryOrderComparator;
078: import net.jforum.util.preferences.ConfigKeys;
079: import net.jforum.util.preferences.SystemGlobals;
080:
081: /**
082: * Repository for the forums of the System.
083: * This repository acts like a cache system, to avoid repetitive and unnecessary SQL queries
084: * every time we need some info about the forums.
085: * To start the repository, call the method <code>start(ForumModel, CategoryModel)</code>
086: *
087: * @author Rafael Steil
088: * @version $Id: ForumRepository.java,v 1.60 2007/09/10 23:06:59 rafaelsteil Exp $
089: */
090: public class ForumRepository implements Cacheable {
091: private static CacheEngine cache;
092: private static ForumRepository instance;
093: private static Logger logger = Logger
094: .getLogger(ForumRepository.class);
095:
096: private static final String FQN = "forumRepository";
097: private static final String CATEGORIES_SET = "categoriesSet";
098: private static final String RELATION = "relationForums";
099: private static final String FQN_MODERATORS = FQN + "/moderators";
100: private static final String TOTAL_MESSAGES = "totalMessages";
101: private static final String MOST_USERS_ONLINE = "mostUsersEverOnline";
102: private static final String LOADED = "loaded";
103: private static final String LAST_USER = "lastUser";
104: private static final String TOTAL_USERS = "totalUsers";
105:
106: /**
107: * @see net.jforum.cache.Cacheable#setCacheEngine(net.jforum.cache.CacheEngine)
108: */
109: public void setCacheEngine(CacheEngine engine) {
110: cache = engine;
111: }
112:
113: /**
114: * Starts the repository.
115: *
116: * @param fm The <code>ForumModel</code> instance which will be
117: * used to retrieve information about the forums.
118: * @param cm The <code>CategoryModel</code> instance which will
119: * be used to retrieve information about the categories.
120: * @param configModel ConfigDAO
121: */
122: public synchronized static void start(ForumDAO fm, CategoryDAO cm,
123: ConfigDAO configModel) {
124: instance = new ForumRepository();
125:
126: if (cache.get(FQN, LOADED) == null) {
127: instance.loadCategories(cm);
128: instance.loadForums(fm);
129: instance.loadMostUsersEverOnline(configModel);
130: instance.loadUsersInfo();
131:
132: Integer i = (Integer) cache.get(FQN, TOTAL_MESSAGES);
133:
134: if (i == null) {
135: cache.add(FQN, TOTAL_MESSAGES, new Integer(0));
136: }
137:
138: cache.add(FQN, LOADED, "1");
139: }
140: }
141:
142: /**
143: * Gets a category by its id.
144: * A call to @link #getCategory(int, int) is made, using the
145: * return of <code>SessionFacade.getUserSession().getUserId()</code>
146: * as argument for the "userId" parameter.
147: *
148: * @param categoryId The id of the category to check
149: * @return <code>null</code> if the category is either not
150: * found or access is denied.
151: * @see #getCategory(int, int)
152: */
153: public static Category getCategory(int categoryId) {
154: return getCategory(SessionFacade.getUserSession().getUserId(),
155: categoryId);
156: }
157:
158: /**
159: * Gets a category by its id.
160: *
161: * @param userId The user id who is requesting the category
162: * @param categoryId The id of the category to get
163: * @return <code>null</code> if the category is either not
164: * found or access is denied.
165: * @see #getCategory(int)
166: */
167: public static Category getCategory(int userId, int categoryId) {
168: if (!isCategoryAccessible(userId, categoryId)) {
169: return null;
170: }
171:
172: return (Category) cache.get(FQN, Integer.toString(categoryId));
173: }
174:
175: public static Category getCategory(PermissionControl pc,
176: int categoryId) {
177: if (!isCategoryAccessible(pc, categoryId)) {
178: return null;
179: }
180:
181: return (Category) cache.get(FQN, Integer.toString(categoryId));
182: }
183:
184: public static Category retrieveCategory(int categoryId) {
185: return (Category) cache.get(FQN, Integer.toString(categoryId));
186: }
187:
188: /**
189: * Check is some category is accessible.
190: *
191: * @param userId The user's id who is trying to get the category
192: * @param categoryId The category's id to check for access rights
193: * @return <code>true</code> if access to the category is allowed.
194: */
195: public static boolean isCategoryAccessible(int userId,
196: int categoryId) {
197: return isCategoryAccessible(SecurityRepository.get(userId),
198: categoryId);
199: }
200:
201: /**
202: * Check if some category is accessible.
203: *
204: * @param categoryId The category id to check for access rights
205: * @return <code>true</code> if access to the category is allowed.
206: */
207: public static boolean isCategoryAccessible(int categoryId) {
208: return isCategoryAccessible(SessionFacade.getUserSession()
209: .getUserId(), categoryId);
210: }
211:
212: /**
213: * Check is some category is accessible.
214: *
215: * @param pc The <code>PermissionControl</code> instance containing
216: * all security info related to the user.
217: * @param categoryId the category's id to check for access rights
218: * @return <code>true</code> if access to the category is allowed.
219: */
220: public static boolean isCategoryAccessible(PermissionControl pc,
221: int categoryId) {
222: return pc.canAccess(SecurityConstants.PERM_CATEGORY, Integer
223: .toString(categoryId));
224: }
225:
226: /**
227: * Gets all categories from the cache.
228: *
229: * @param userId int
230: * @return <code>List</code> with the categories. Each entry is a <code>Category</code> object.
231: */
232: public static List getAllCategories(int userId) {
233: PermissionControl pc = SecurityRepository.get(userId);
234: List l = new ArrayList();
235:
236: Set categoriesSet = (Set) cache.get(FQN, CATEGORIES_SET);
237:
238: if (categoriesSet == null) {
239: synchronized (ForumRepository.instance) {
240: if (categoriesSet == null) {
241: logger
242: .warn("Categories set returned null from the cache. Trying to reload");
243:
244: try {
245: ForumRepository.instance
246: .loadCategories(DataAccessDriver
247: .getInstance().newCategoryDAO());
248: ForumRepository.instance
249: .loadForums(DataAccessDriver
250: .getInstance().newForumDAO());
251: } catch (Exception e) {
252: throw new CategoryNotFoundException(
253: "Failed to get the category", e);
254: }
255:
256: categoriesSet = (Set) cache
257: .get(FQN, CATEGORIES_SET);
258:
259: if (categoriesSet == null) {
260: throw new CategoryNotFoundException(
261: "Could not find all categories. There must be a problem with the cache");
262: }
263: }
264: }
265: }
266:
267: for (Iterator iter = categoriesSet.iterator(); iter.hasNext();) {
268: Category c = getCategory(pc, ((Category) iter.next())
269: .getId());
270:
271: if (c != null) {
272: l.add(c);
273: }
274: }
275:
276: return l;
277: }
278:
279: /**
280: * Get all categories.
281: * A call to @link #getAllCategories(int) is made, passing
282: * the return of <code>SessionFacade.getUserSession().getUserId()</code>
283: * as the value for the "userId" argument.
284: *
285: * @return <code>List</code> with the categories. Each entry is a <code>Category</code> object.
286: * @see #getAllCategories(int)
287: */
288: public static List getAllCategories() {
289: return getAllCategories(SessionFacade.getUserSession()
290: .getUserId());
291: }
292:
293: private static Category findCategoryByOrder(int order) {
294: for (Iterator iter = ((Set) cache.get(FQN, CATEGORIES_SET))
295: .iterator(); iter.hasNext();) {
296: Category c = (Category) iter.next();
297: if (c.getOrder() == order) {
298: return c;
299: }
300: }
301:
302: return null;
303: }
304:
305: /**
306: * Updates some category.
307: * This method only updated the "name" and "order" fields.
308: *
309: * @param c The category to update. The method will search for a category
310: * with the same id and update its data.
311: */
312: public synchronized static void reloadCategory(Category c) {
313: Category current = (Category) cache.get(FQN, Integer.toString(c
314: .getId()));
315: Category currentAtOrder = findCategoryByOrder(c.getOrder());
316:
317: Set tmpSet = new TreeSet(new CategoryOrderComparator());
318: tmpSet.addAll((Set) cache.get(FQN, CATEGORIES_SET));
319:
320: if (currentAtOrder != null) {
321: tmpSet.remove(currentAtOrder);
322: cache.remove(FQN, Integer.toString(currentAtOrder.getId()));
323: }
324:
325: tmpSet.add(c);
326: cache.add(FQN, Integer.toString(c.getId()), c);
327:
328: if (currentAtOrder != null
329: && c.getId() != currentAtOrder.getId()) {
330: tmpSet.remove(current);
331: currentAtOrder.setOrder(current.getOrder());
332: tmpSet.add(currentAtOrder);
333:
334: cache.add(FQN, Integer.toString(currentAtOrder.getId()),
335: currentAtOrder);
336: }
337:
338: cache.add(FQN, CATEGORIES_SET, tmpSet);
339: }
340:
341: /**
342: * Refreshes a category entry in the cache.
343: *
344: * @param c The category to refresh
345: */
346: public synchronized static void refreshCategory(Category c) {
347: cache.add(FQN, Integer.toString(c.getId()), c);
348: Set s = (Set) cache.get(FQN, CATEGORIES_SET);
349: s.remove(c);
350: s.add(c);
351: cache.add(FQN, CATEGORIES_SET, s);
352: }
353:
354: public synchronized static void refreshForum(Forum forum) {
355: Category c = retrieveCategory(forum.getCategoryId());
356: c.addForum(forum);
357: refreshCategory(c);
358: }
359:
360: /**
361: * Remove a category from the cache
362: * @param c The category to remove. The instance should have the
363: * category id at least
364: */
365: public synchronized static void removeCategory(Category c) {
366: cache.remove(FQN, Integer.toString(c.getId()));
367:
368: Set s = (Set) cache.get(FQN, CATEGORIES_SET);
369: s.remove(c);
370: cache.add(FQN, CATEGORIES_SET, s);
371:
372: Map m = (Map) cache.get(FQN, RELATION);
373: for (Iterator iter = m.values().iterator(); iter.hasNext();) {
374: if (Integer.parseInt((String) iter.next()) == c.getId()) {
375: iter.remove();
376: }
377: }
378:
379: cache.add(FQN, RELATION, m);
380: }
381:
382: /**
383: * Adds a new category to the cache.
384: * @param c The category instance to insert in the cache.
385: */
386: public synchronized static void addCategory(Category c) {
387: String categoryId = Integer.toString(c.getId());
388: cache.add(FQN, categoryId, c);
389:
390: Set s = (Set) cache.get(FQN, CATEGORIES_SET);
391:
392: if (s == null) {
393: s = new TreeSet(new CategoryOrderComparator());
394: }
395:
396: s.add(c);
397: cache.add(FQN, CATEGORIES_SET, s);
398:
399: Map relation = (Map) cache.get(FQN, RELATION);
400: if (relation == null) {
401: relation = new HashMap();
402: }
403:
404: for (Iterator iter = c.getForums().iterator(); iter.hasNext();) {
405: Forum f = (Forum) iter.next();
406: relation.put(Integer.toString(f.getId()), categoryId);
407: }
408:
409: cache.add(FQN, RELATION, relation);
410: }
411:
412: /**
413: * Gets a specific forum from the cache.
414: *
415: * @param forumId The forum's ID to get
416: * @return <code>net.jforum.Forum</code> object instance or <code>null</code>
417: * if the forum was not found or is not accessible to the user.
418: */
419: public static Forum getForum(int forumId) {
420: String categoryId = (String) ((Map) cache.get(FQN, RELATION))
421: .get(Integer.toString(forumId));
422:
423: if (categoryId != null) {
424: Category category = (Category) cache.get(FQN, categoryId);
425:
426: if (isCategoryAccessible(category.getId())) {
427: return category.getForum(forumId);
428: }
429: }
430:
431: return null;
432: }
433:
434: public static boolean isForumAccessible(int forumId) {
435: return isForumAccessible(SessionFacade.getUserSession()
436: .getUserId(), forumId);
437: }
438:
439: public static boolean isForumAccessible(int userId, int forumId) {
440: int categoryId = Integer.parseInt((String) ((Map) cache.get(
441: FQN, RELATION)).get(Integer.toString(forumId)));
442: return isForumAccessible(userId, categoryId, forumId);
443: }
444:
445: public static boolean isForumAccessible(int userId, int categoryId,
446: int forumId) {
447: return ((Category) cache.get(FQN, Integer.toString(categoryId)))
448: .getForum(userId, forumId) != null;
449: }
450:
451: /**
452: * Adds a new forum to the cache repository.
453: *
454: * @param forum The forum to add
455: */
456: public synchronized static void addForum(Forum forum) {
457: String categoryId = Integer.toString(forum.getCategoryId());
458:
459: Category c = (Category) cache.get(FQN, categoryId);
460: c.addForum(forum);
461: cache.add(FQN, categoryId, c);
462:
463: Map m = (Map) cache.get(FQN, RELATION);
464: m.put(Integer.toString(forum.getId()), categoryId);
465: cache.add(FQN, RELATION, m);
466:
467: Set s = (Set) cache.get(FQN, CATEGORIES_SET);
468: cache.add(FQN, CATEGORIES_SET, s);
469: }
470:
471: /**
472: * Removes a forum from the cache.
473: *
474: * @param forum The forum instance to remove.
475: */
476: public synchronized static void removeForum(Forum forum) {
477: String id = Integer.toString(forum.getId());
478: Map m = (Map) cache.get(FQN, RELATION);
479: m.remove(id);
480: cache.add(FQN, RELATION, m);
481:
482: id = Integer.toString(forum.getCategoryId());
483:
484: Category c = (Category) cache.get(FQN, id);
485: c.removeForum(forum.getId());
486: cache.add(FQN, id, c);
487:
488: Set s = (Set) cache.get(FQN, CATEGORIES_SET);
489: cache.add(FQN, CATEGORIES_SET, s);
490: }
491:
492: /**
493: * Reloads a forum.
494: * The forum should already be in the cache and <b>SHOULD NOT</b>
495: * have its order changed. If the forum's order was changed,
496: * then you <b>MUST CALL</b> @link Category#changeForumOrder(Forum) <b>BEFORE</b>
497: * calling this method.
498: *
499: * @param forumId int The forum to reload its information
500: */
501: public static synchronized void reloadForum(int forumId) {
502: Forum f = DataAccessDriver.getInstance().newForumDAO()
503: .selectById(forumId);
504:
505: if (((Map) cache.get(FQN, RELATION)).containsKey(Integer
506: .toString(forumId))) {
507: String id = Integer.toString(f.getCategoryId());
508: Category c = (Category) cache.get(FQN, id);
509:
510: f.setLastPostInfo(null);
511: f.setLastPostInfo(ForumRepository.getLastPostInfo(f));
512: c.reloadForum(f);
513:
514: cache.add(FQN, id, c);
515: Set s = (Set) cache.get(FQN, CATEGORIES_SET);
516: cache.add(FQN, CATEGORIES_SET, s);
517: }
518:
519: getTotalMessages(true);
520: }
521:
522: public static synchronized void updateForumStats(Topic t, User u,
523: Post p) {
524: String f = Integer.toString(t.getForumId());
525:
526: if (((Map) cache.get(FQN, RELATION)).containsKey(f)) {
527: Forum forum = getForum(t.getForumId());
528:
529: SimpleDateFormat df = new SimpleDateFormat(SystemGlobals
530: .getValue(ConfigKeys.DATE_TIME_FORMAT));
531:
532: LastPostInfo lpi = forum.getLastPostInfo();
533:
534: if (lpi == null) {
535: lpi = new LastPostInfo();
536: }
537:
538: lpi.setPostId(p.getId());
539: lpi.setPostDate(df.format(p.getTime()));
540: lpi.setPostTimeMillis(p.getTime().getTime());
541: lpi.setTopicId(t.getId());
542: lpi.setTopicReplies(t.getTotalReplies());
543: lpi.setUserId(u.getId());
544: lpi.setUsername(u.getUsername());
545:
546: forum.setLastPostInfo(lpi);
547:
548: if (t.getTotalReplies() == 0) {
549: forum.setTotalTopics(forum.getTotalTopics() + 1);
550: }
551:
552: forum.setTotalPosts(forum.getTotalPosts() + 1);
553:
554: Category c = retrieveCategory(forum.getCategoryId());
555: c.reloadForum(forum);
556:
557: refreshCategory(c);
558: }
559: }
560:
561: /**
562: * Gets information about the last message posted in some forum.
563: * @param forum The forum to retrieve information
564: * @return LastPostInfo
565: */
566: public static LastPostInfo getLastPostInfo(Forum forum) {
567: LastPostInfo lpi = forum.getLastPostInfo();
568:
569: if (lpi == null || !forum.getLastPostInfo().hasInfo()) {
570: lpi = DataAccessDriver.getInstance().newForumDAO()
571: .getLastPostInfo(forum.getId());
572: forum.setLastPostInfo(lpi);
573: }
574:
575: return lpi;
576: }
577:
578: /**
579: * Gets information about the last message posted in some forum.
580: *
581: * @param forumId The forum's id to retrieve information
582: * @return LastPostInfo
583: */
584: public static LastPostInfo getLastPostInfo(int forumId) {
585: return getLastPostInfo(getForum(forumId));
586: }
587:
588: /**
589: * Gets information about the moderators of some forum.
590: * @param forumId The forum to retrieve information
591: * @return List
592: */
593: public static List getModeratorList(int forumId) {
594: List l = (List) cache.get(FQN_MODERATORS, Integer
595: .toString(forumId));
596:
597: if (l == null) {
598: synchronized (FQN_MODERATORS) {
599: try {
600: l = DataAccessDriver.getInstance().newForumDAO()
601: .getModeratorList(forumId);
602: cache.add(FQN_MODERATORS,
603: Integer.toString(forumId), l);
604: } catch (Exception e) {
605: throw new DatabaseException(e);
606: }
607: }
608: }
609:
610: return l;
611: }
612:
613: public static void clearModeratorList() {
614: cache.remove(FQN_MODERATORS);
615: }
616:
617: public static User lastRegisteredUser() {
618: return (User) cache.get(FQN, LAST_USER);
619: }
620:
621: public static void setLastRegisteredUser(User user) {
622: cache.add(FQN, LAST_USER, user);
623: }
624:
625: public static Integer totalUsers() {
626: return (Integer) cache.get(FQN, TOTAL_USERS);
627: }
628:
629: public static void incrementTotalUsers() {
630: Integer i = (Integer) cache.get(FQN, TOTAL_USERS);
631:
632: if (i == null) {
633: i = new Integer(0);
634: }
635:
636: cache.add(FQN, TOTAL_USERS, new Integer(i.intValue() + 1));
637: }
638:
639: /**
640: * Gets the number of messages in the entire board.
641: * @return int
642: * @see #getTotalMessages(boolean)
643: */
644: public static int getTotalMessages() {
645: return getTotalMessages(false);
646: }
647:
648: /**
649: * Gets the number of messags in the entire board.
650: *
651: * @param fromDb If <code>true</code>, a query to the database will
652: * be made, to retrieve the desired information. If <code>false</code>, the
653: * data will be fetched from the cache.
654: * @return The number of messages posted in the board.
655: * @see #getTotalMessages()
656: */
657: public static int getTotalMessages(boolean fromDb) {
658: Integer i = (Integer) cache.get(FQN, TOTAL_MESSAGES);
659:
660: int total = i != null ? i.intValue() : 0;
661:
662: if (fromDb || total == 0) {
663: total = DataAccessDriver.getInstance().newForumDAO()
664: .getTotalMessages();
665: cache.add(FQN, TOTAL_MESSAGES, new Integer(total));
666: }
667:
668: return total;
669: }
670:
671: public static synchronized void incrementTotalMessages() {
672: int total = ((Integer) cache.get(FQN, TOTAL_MESSAGES))
673: .intValue();
674: cache.add(FQN, TOTAL_MESSAGES, new Integer(total + 1));
675: }
676:
677: /**
678: * Gets the number of most online users ever
679: * @return MostUsersEverOnline
680: */
681: public static MostUsersEverOnline getMostUsersEverOnline() {
682: MostUsersEverOnline online = (MostUsersEverOnline) cache.get(
683: FQN, MOST_USERS_ONLINE);
684:
685: if (online == null) {
686: synchronized (MOST_USERS_ONLINE) {
687: online = (MostUsersEverOnline) cache.get(FQN,
688: MOST_USERS_ONLINE);
689:
690: if (online == null) {
691: online = instance
692: .loadMostUsersEverOnline(DataAccessDriver
693: .getInstance().newConfigDAO());
694: }
695: }
696: }
697:
698: return online;
699: }
700:
701: /**
702: * Update the value of most online users ever.
703: *
704: * @param m MostUsersEverOnline The new value to store. Generally it
705: * will be a bigger one.
706: */
707: public static void updateMostUsersEverOnline(MostUsersEverOnline m) {
708: ConfigDAO cm = DataAccessDriver.getInstance().newConfigDAO();
709: Config config = cm
710: .selectByName(ConfigKeys.MOST_USERS_EVER_ONLINE);
711:
712: if (config == null) {
713: // Total
714: config = new Config();
715: config.setName(ConfigKeys.MOST_USERS_EVER_ONLINE);
716: config.setValue(Integer.toString(m.getTotal()));
717:
718: cm.insert(config);
719:
720: // Date
721: config.setName(ConfigKeys.MOST_USER_EVER_ONLINE_DATE);
722: config.setValue(Long.toString(m.getTimeInMillis()));
723:
724: cm.insert(config);
725: } else {
726: // Total
727: config.setValue(Integer.toString(m.getTotal()));
728: cm.update(config);
729:
730: // Date
731: config.setName(ConfigKeys.MOST_USER_EVER_ONLINE_DATE);
732: config.setValue(Long.toString(m.getTimeInMillis()));
733: cm.update(config);
734: }
735:
736: cache.add(FQN, MOST_USERS_ONLINE, m);
737: }
738:
739: /**
740: * Loads all forums.
741: * @param fm ForumDAO
742: */
743: private void loadForums(ForumDAO fm) {
744: List l = fm.selectAll();
745:
746: Map m = (Map) cache.get(FQN, RELATION);
747: if (m == null) {
748: m = new HashMap();
749: }
750:
751: int lastId = 0;
752: Category c = null;
753: String catId = null;
754:
755: for (Iterator iter = l.iterator(); iter.hasNext();) {
756: Forum f = (Forum) iter.next();
757:
758: if (f.getCategoryId() != lastId) {
759: if (c != null) {
760: cache.add(FQN, catId, c);
761: }
762:
763: lastId = f.getCategoryId();
764: catId = Integer.toString(f.getCategoryId());
765: c = (Category) cache.get(FQN, catId);
766: }
767:
768: if (c == null) {
769: throw new CategoryNotFoundException(
770: "Category for forum #" + f.getId()
771: + " not found");
772: }
773:
774: String forumId = Integer.toString(f.getId());
775: c.addForum(f);
776: m.put(forumId, catId);
777: }
778:
779: if (c != null) {
780: cache.add(FQN, catId, c);
781: }
782:
783: cache.add(FQN, RELATION, m);
784: }
785:
786: private void loadUsersInfo() {
787: UserDAO udao = DataAccessDriver.getInstance().newUserDAO();
788: cache.add(FQN, LAST_USER, udao.getLastUserInfo());
789: cache.add(FQN, TOTAL_USERS, new Integer(udao.getTotalUsers()));
790: }
791:
792: /**
793: * Loads all categories.
794: * @param cm CategoryDAO
795: */
796: private void loadCategories(CategoryDAO cm) {
797: List categories = cm.selectAll();
798: Set categoriesSet = new TreeSet(new CategoryOrderComparator());
799:
800: for (Iterator iter = categories.iterator(); iter.hasNext();) {
801: Category c = (Category) iter.next();
802:
803: cache.add(FQN, Integer.toString(c.getId()), c);
804: categoriesSet.add(c);
805: }
806:
807: cache.add(FQN, CATEGORIES_SET, categoriesSet);
808: }
809:
810: private MostUsersEverOnline loadMostUsersEverOnline(ConfigDAO cm) {
811: Config config = cm
812: .selectByName(ConfigKeys.MOST_USERS_EVER_ONLINE);
813: MostUsersEverOnline mostUsersEverOnline = new MostUsersEverOnline();
814:
815: if (config != null) {
816: mostUsersEverOnline.setTotal(Integer.parseInt(config
817: .getValue()));
818:
819: // We're assuming that, if we have one key, the another one
820: // will always exist
821: config = cm
822: .selectByName(ConfigKeys.MOST_USER_EVER_ONLINE_DATE);
823: mostUsersEverOnline.setTimeInMillis(Long.parseLong(config
824: .getValue()));
825: }
826:
827: cache.add(FQN, MOST_USERS_ONLINE, mostUsersEverOnline);
828:
829: return mostUsersEverOnline;
830: }
831:
832: public static String getListAllowedForums() {
833: int n = 0;
834: StringBuffer buf = new StringBuffer();
835:
836: List allCategories = ForumRepository.getAllCategories();
837:
838: for (Iterator iter = allCategories.iterator(); iter.hasNext();) {
839: Collection forums = ((Category) iter.next()).getForums();
840:
841: for (Iterator tmpIterator = forums.iterator(); tmpIterator
842: .hasNext();) {
843: Forum f = (Forum) tmpIterator.next();
844:
845: if (ForumRepository.isForumAccessible(f.getId())) {
846: if (n++ > 0) {
847: buf.append(',');
848: }
849:
850: buf.append(f.getId());
851: }
852: }
853: }
854:
855: if (n <= 0) {
856: return "-1";
857: }
858:
859: return buf.toString();
860: }
861: }
|