001: /*
002: * NEMESIS-FORUM.
003: * Copyright (C) 2002 David Laurent(lithium2@free.fr). All rights reserved.
004: *
005: * Copyright (c) 2000 The Apache Software Foundation. All rights reserved.
006: *
007: * Copyright (C) 2001 Yasna.com. All rights reserved.
008: *
009: * Copyright (C) 2000 CoolServlets.com. All rights reserved.
010: *
011: * NEMESIS-FORUM. is free software; you can redistribute it and/or
012: * modify it under the terms of the Apache Software License, Version 1.1,
013: * or (at your option) any later version.
014: *
015: * NEMESIS-FORUM core framework, NEMESIS-FORUM backoffice, NEMESIS-FORUM frontoffice
016: * application are parts of NEMESIS-FORUM and are distributed under
017: * same terms of licence.
018: *
019: *
020: * NEMESIS-FORUM includes software developed by the Apache Software Foundation (http://www.apache.org/)
021: * and software developed by CoolServlets.com (http://www.coolservlets.com).
022: * and software developed by Yasna.com (http://www.yasna.com).
023: *
024: */
025: package org.nemesis.forum.impl;
026:
027: import java.sql.Connection;
028: import java.sql.PreparedStatement;
029: import java.sql.ResultSet;
030: import java.sql.SQLException;
031: import java.util.Iterator;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035: import org.nemesis.forum.ForumThread;
036: import org.nemesis.forum.Message;
037: import org.nemesis.forum.exception.ForumMessageNotFoundException;
038: import org.nemesis.forum.util.jdbc.DbConnectionManager;
039:
040: /**
041: * Database implementation of Iterator for ForumMesages in a ForumThread.
042: */
043: public class DbThreadIterator implements Iterator {
044: static protected Log log = LogFactory
045: .getLog(DbThreadIterator.class);
046: /** DATABASE QUERIES **/
047: private static final String MESSAGE_COUNT = "SELECT count(messageID) FROM yazdMessage WHERE threadID=?";
048: private static final String MESSAGE_COUNT_APPROVED = "SELECT count(messageID) FROM yazdMessage WHERE threadID=? AND approved=?";
049: private static final String GET_MESSAGES = "SELECT messageID, creationDate FROM yazdMessage WHERE threadID=? "
050: + "ORDER BY creationDate ASC";
051: private static final String GET_MESSAGES_APPROVED = "SELECT messageID, creationDate FROM yazdMessage WHERE threadID=? AND approved=? ORDER BY creationDate ASC";
052:
053: private ForumThread thread;
054: private int[] messages;
055: private int currentIndex = -1;
056:
057: private Message nextMessage = null;
058:
059: protected DbThreadIterator(ForumThread thread) {
060: this .thread = thread;
061: Connection con = null;
062: PreparedStatement pstmt = null;
063: try {
064: con = DbConnectionManager.getConnection();
065: pstmt = con.prepareStatement(MESSAGE_COUNT);
066: pstmt.setInt(1, thread.getID());
067: ResultSet rs = pstmt.executeQuery();
068: rs.next();
069: messages = new int[rs.getInt(1)];
070: pstmt.close();
071:
072: pstmt = con.prepareStatement(GET_MESSAGES);
073: pstmt.setInt(1, thread.getID());
074: rs = pstmt.executeQuery();
075: for (int i = 0; i < messages.length; i++) {
076: rs.next();
077: messages[i] = rs.getInt(1);
078: }
079: } catch (SQLException sqle) {
080: log.error("Error in DbThreadIterator:constructor()-", sqle);
081: } finally {
082: try {
083: pstmt.close();
084: } catch (Exception e) {
085: log.error("", e);
086: }
087: try {
088: con.close();
089: } catch (Exception e) {
090: log.error("", e);
091: }
092: }
093: }
094:
095: protected DbThreadIterator(ForumThread thread, int startIndex,
096: int numResults) {
097: this .thread = thread;
098:
099: int[] tempMessages = new int[numResults];
100: //It's very possible that there might not be as many messages to get
101: //as we requested. Therefore, we keep track of how many messages we
102: //get by keeping a messageCount.
103: int messageCount = 0;
104:
105: Connection con = null;
106: PreparedStatement pstmt = null;
107:
108: try {
109: con = DbConnectionManager.getConnection();
110: pstmt = con.prepareStatement(GET_MESSAGES);
111: pstmt.setInt(1, thread.getID());
112:
113: ResultSet rs = pstmt.executeQuery();
114: //Move to start of index
115: for (int i = 0; i < startIndex; i++) {
116: rs.next();
117: }
118: //Now read in desired number of results
119: for (int i = 0; i < numResults; i++) {
120: if (rs.next()) {
121: tempMessages[messageCount] = rs.getInt("messageID");
122: messageCount++;
123: } else {
124: break;
125: }
126: }
127: } catch (SQLException sqle) {
128: log.error("Error in DbThreadIterator:constructor()-", sqle);
129: } finally {
130: try {
131: pstmt.close();
132: } catch (Exception e) {
133: log.error("", e);
134: }
135: try {
136: con.close();
137: } catch (Exception e) {
138: log.error("", e);
139: }
140: }
141: messages = new int[messageCount];
142: for (int i = 0; i < messageCount; i++) {
143: messages[i] = tempMessages[i];
144: }
145: }
146:
147: protected DbThreadIterator(boolean approved, ForumThread thread) {
148: this .thread = thread;
149: Connection con = null;
150: PreparedStatement pstmt = null;
151: try {
152: con = DbConnectionManager.getConnection();
153: pstmt = con.prepareStatement(MESSAGE_COUNT_APPROVED);
154: pstmt.setInt(1, thread.getID());
155: pstmt.setInt(2, approved ? 1 : 0);
156:
157: ResultSet rs = pstmt.executeQuery();
158: rs.next();
159: messages = new int[rs.getInt(1)];
160: pstmt.close();
161:
162: pstmt = con.prepareStatement(GET_MESSAGES_APPROVED);
163: pstmt.setInt(1, thread.getID());
164: pstmt.setInt(2, approved ? 1 : 0);
165: rs = pstmt.executeQuery();
166: for (int i = 0; i < messages.length; i++) {
167: rs.next();
168: messages[i] = rs.getInt(1);
169: }
170: } catch (SQLException sqle) {
171: log.error("Error in DbThreadIterator:constructor()-", sqle);
172: } finally {
173: try {
174: pstmt.close();
175: } catch (Exception e) {
176: log.error("", e);
177: }
178: try {
179: con.close();
180: } catch (Exception e) {
181: log.error("", e);
182: }
183: }
184: }
185:
186: protected DbThreadIterator(boolean approved, ForumThread thread,
187: int startIndex, int numResults) {
188: this .thread = thread;
189:
190: int[] tempMessages = new int[numResults];
191: //It's very possible that there might not be as many messages to get
192: //as we requested. Therefore, we keep track of how many messages we
193: //get by keeping a messageCount.
194: int messageCount = 0;
195:
196: Connection con = null;
197: PreparedStatement pstmt = null;
198:
199: try {
200: con = DbConnectionManager.getConnection();
201: pstmt = con.prepareStatement(GET_MESSAGES_APPROVED);
202: pstmt.setInt(1, thread.getID());
203: pstmt.setInt(2, approved ? 1 : 0);
204: ResultSet rs = pstmt.executeQuery();
205: //Move to start of index
206: for (int i = 0; i < startIndex; i++) {
207: rs.next();
208: }
209: //Now read in desired number of results
210: for (int i = 0; i < numResults; i++) {
211: if (rs.next()) {
212: tempMessages[messageCount] = rs.getInt("messageID");
213: messageCount++;
214: } else {
215: break;
216: }
217: }
218: } catch (SQLException sqle) {
219: log.error("Error in DbThreadIterator:constructor()-", sqle);
220: } finally {
221: try {
222: pstmt.close();
223: } catch (Exception e) {
224: log.error("", e);
225: }
226: try {
227: con.close();
228: } catch (Exception e) {
229: log.error("", e);
230: }
231: }
232: messages = new int[messageCount];
233: for (int i = 0; i < messageCount; i++) {
234: messages[i] = tempMessages[i];
235: }
236: }
237:
238: /**
239: * Returns true if there are more messages in the list.
240: *
241: * @return true if the iterator has more elements.
242: */
243: public boolean hasNext() {
244: //If we are at the end of the list, there can't be any more messages
245: //to iterate through.
246: if (currentIndex + 1 >= messages.length) {
247: return false;
248: }
249: return true;
250:
251: /*
252: BUG: this code calls getNextMessage() which will increment the
253: currentIndex variable as a result of calling this message!
254:
255: //Otherwise, see if nextMessage is null. If so, try to load the next
256: //message to make sure it exists.
257:
258: // hmm, do we really need to do this here? i think it should be left up
259: // to the next() method -- BL
260:
261: if (nextMessage == null) {
262: nextMessage = getNextMessage();
263: if (nextMessage == null) {
264: return false;
265: }
266: }
267: return true;
268: */
269: }
270:
271: /**
272: * Returns the next message in the interation.
273: *
274: * @return the next message in the interation.
275: * @throws NoSuchElementException if the iteration has no more elements.
276: */
277: public Object next() throws java.util.NoSuchElementException {
278: Message message = null;
279: if (nextMessage != null) {
280: message = nextMessage;
281: nextMessage = null;
282: } else {
283: message = getNextMessage();
284: if (message == null) {
285: throw new java.util.NoSuchElementException();
286: }
287: }
288: return message;
289: }
290:
291: /**
292: * Not supported for security reasons. Use the deleteMessage method in the
293: * ForumThread class instead.
294: *
295: * @see ForumThread#deleteMessage(ForumMessage)
296: */
297: public void remove() throws UnsupportedOperationException {
298: throw new UnsupportedOperationException();
299: }
300:
301: /**
302: * Returns the next available message, or null if there are no more
303: * messages to return.
304: */
305: private Message getNextMessage() {
306: while (currentIndex + 1 < messages.length) {
307: currentIndex++;
308: try {
309: Message message = thread
310: .getMessage(messages[currentIndex]);
311: return message;
312: } catch (ForumMessageNotFoundException mnfe) {
313: }
314: }
315: return null;
316: }
317: }
|