KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > nemesis > forum > impl > DbSequenceManager


1 /*
2  * NEMESIS-FORUM.
3  * Copyright (C) 2002 David Laurent(lithium2@free.fr). All rights reserved.
4  *
5  * Copyright (c) 2000 The Apache Software Foundation. All rights reserved.
6  *
7  * Copyright (C) 2001 Yasna.com. All rights reserved.
8  *
9  * Copyright (C) 2000 CoolServlets.com. All rights reserved.
10  *
11  * NEMESIS-FORUM. is free software; you can redistribute it and/or
12  * modify it under the terms of the Apache Software License, Version 1.1,
13  * or (at your option) any later version.
14  *
15  * NEMESIS-FORUM core framework, NEMESIS-FORUM backoffice, NEMESIS-FORUM frontoffice
16  * application are parts of NEMESIS-FORUM and are distributed under
17  * same terms of licence.
18  *
19  *
20  * NEMESIS-FORUM includes software developed by the Apache Software Foundation (http://www.apache.org/)
21  * and software developed by CoolServlets.com (http://www.coolservlets.com).
22  * and software developed by Yasna.com (http://www.yasna.com).
23  *
24  */

25
26
27
28 package org.nemesis.forum.impl;
29
30 import java.sql.Connection JavaDoc;
31 import java.sql.PreparedStatement JavaDoc;
32 import java.sql.ResultSet JavaDoc;
33 import java.util.HashMap JavaDoc;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.nemesis.forum.util.jdbc.DbConnectionManager;
38
39 /**
40  * Manages sequences of unique ID's that get stored in the database. Database
41  * support for sequences varies widely; some don't support them at all. So,
42  * we handle unique ID generation with synchronized counters.<p>
43  *
44  * Selecting the initial ID for each sequence is trivial: we simply query the
45  * database to get the last highest unique ID, and then add 1 to that.<p>
46  *
47  * This method only works if a single instance is pointed at a database.
48  * Otherwise, the unique ID's will stop being unique. :) A refined class that
49  * deals with this is coming soon.
50  */

51 public class DbSequenceManager {
52     static protected Log log = LogFactory.getLog(DbSequenceManager.class);
53     private static final String JavaDoc NEXT_FORUM_ID = "SELECT max(forumID) FROM yazdForum";
54     private static final String JavaDoc NEXT_THREAD_ID = "SELECT max(threadID) FROM yazdThread";
55     private static final String JavaDoc NEXT_MESSAGE_ID = "SELECT max(messageID) FROM yazdMessage";
56     private static final String JavaDoc NEXT_GROUP_ID = "SELECT max(groupID) FROM yazdGroup";
57     private static final String JavaDoc NEXT_USER_ID = "SELECT max(userID) FROM yazdUser";
58
59     /**
60      * Singleton type access to the class.
61      */

62     private static DbSequenceManager sequenceManager = null;
63
64     /**
65      * Lock so that we can synchronize during initialization.
66      */

67     private static Object JavaDoc initLock = new Object JavaDoc();
68
69     /**
70      * Returns the next ID of the specified type.
71      *
72      * @param type the type of unique ID.
73      * @return the next unique ID of the specified type.
74      */

75     public static int nextID(String JavaDoc type) {
76         if (sequenceManager == null) {
77             synchronized(initLock) {
78                 if (sequenceManager == null) {
79                     sequenceManager = new DbSequenceManager();
80                 }
81             }
82         }
83         return sequenceManager.nextUniqueID(type);
84     }
85
86     private HashMap JavaDoc uniqueIDCounters;
87
88     /**
89      * Creates a new DbSequenceManager and initializes all of the counters.
90      */

91     public DbSequenceManager() {
92         uniqueIDCounters = new HashMap JavaDoc();
93         //Forum counter.
94
uniqueIDCounters.put("Forum", new Counter(getNextDbID(NEXT_FORUM_ID)));
95         //ForumThread counter.
96
uniqueIDCounters.put("ForumThread", new Counter(getNextDbID(NEXT_THREAD_ID)));
97         //ForumMessage counter.
98
uniqueIDCounters.put("ForumMessage", new Counter(getNextDbID(NEXT_MESSAGE_ID)));
99         //Group counter.
100
uniqueIDCounters.put("Group", new Counter(getNextDbID(NEXT_GROUP_ID)));
101         //User counter.
102
uniqueIDCounters.put("User", new Counter(getNextDbID(NEXT_USER_ID)));
103     }
104
105     /**
106      * Provides the next available unique ID for a particular object type.
107      * Essentially this provides for the functionality of an auto-increment
108      * database field. Valid counter names are Forum, ForumThread, ForumMessage,
109      * Group, and User.
110      * <p>
111      * Those that are integrating into existing tables should be sure
112      * that the table names match up so that the correct starting unique
113      * id can be determined.
114      */

115     public int nextUniqueID(String JavaDoc counterName) {
116         Counter counter = (Counter)uniqueIDCounters.get(counterName);
117         return counter.next();
118     }
119
120     /**
121      * Do a lookup to see what the next available unique ID is for a
122      * particular table. uses the convention of always making the name of
123      * the column that holds the unique id be called id, so this works.
124      */

125     private int getNextDbID(String JavaDoc query) {
126         int currentID = 0;
127         Connection JavaDoc con = null;
128         PreparedStatement JavaDoc pstmt = null;
129
130         try {
131             con = DbConnectionManager.getConnection();
132             pstmt = con.prepareStatement(query);
133             ResultSet JavaDoc rs = pstmt.executeQuery();
134             rs.next();
135             currentID = rs.getInt(1);
136         }
137         catch( Exception JavaDoc sqle ) {
138             log.error("Error in DbSequenceManager:getNextDbID()-" , sqle);
139             
140         }
141         finally {
142             try { pstmt.close(); }
143             catch (Exception JavaDoc e) { log.error("" , e); }
144             try { con.close(); }
145             catch (Exception JavaDoc e) { log.error("" , e); }
146         }
147         //If the table is empty, start with id 0
148
if (currentID < 0) {
149             currentID = 0;
150         }
151         return currentID;
152     }
153
154     /**
155      * Internal class to keep track of the current count of a unique id.
156      */

157     private final class Counter {
158
159         private int count;
160
161         public Counter(int currentCount) {
162             count = currentCount;
163         }
164
165         public final synchronized int next() {
166             return (++count);
167         }
168     }
169 }
170
Popular Tags