/*
* NEMESIS-FORUM.
* Copyright (C) 2002 David Laurent(lithium2@free.fr). All rights reserved.
*
* Copyright (c) 2000 The Apache Software Foundation. All rights reserved.
*
* Copyright (C) 2001 Yasna.com. All rights reserved.
*
* Copyright (C) 2000 CoolServlets.com. All rights reserved.
*
* NEMESIS-FORUM. is free software; you can redistribute it and/or
* modify it under the terms of the Apache Software License, Version 1.1,
* or (at your option) any later version.
*
* NEMESIS-FORUM core framework, NEMESIS-FORUM backoffice, NEMESIS-FORUM frontoffice
* application are parts of NEMESIS-FORUM and are distributed under
* same terms of licence.
*
*
* NEMESIS-FORUM includes software developed by the Apache Software Foundation (http://www.apache.org/)
* and software developed by CoolServlets.com (http://www.coolservlets.com).
* and software developed by Yasna.com (http://www.yasna.com).
*
*/
package org.nemesis.forum.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nemesis.forum.ForumThread;
import org.nemesis.forum.Message;
import org.nemesis.forum.exception.ForumMessageNotFoundException;
import org.nemesis.forum.util.jdbc.DbConnectionManager;
/**
* Database implementation of Iterator for ForumMesages in a ForumThread.
*/
public class DbThreadIterator implements Iterator {
static protected Log log = LogFactory.getLog(DbThreadIterator.class);
/** DATABASE QUERIES **/
private static final String MESSAGE_COUNT = "SELECT count(messageID) FROM yazdMessage WHERE threadID=?";
private static final String MESSAGE_COUNT_APPROVED = "SELECT count(messageID) FROM yazdMessage WHERE threadID=? AND approved=?";
private static final String GET_MESSAGES = "SELECT messageID, creationDate FROM yazdMessage WHERE threadID=? " + "ORDER BY creationDate ASC";
private static final String GET_MESSAGES_APPROVED = "SELECT messageID, creationDate FROM yazdMessage WHERE threadID=? AND approved=? ORDER BY creationDate ASC";
private ForumThread thread;
private int[] messages;
private int currentIndex = -1;
private Message nextMessage = null;
protected DbThreadIterator(ForumThread thread) {
this.thread = thread;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(MESSAGE_COUNT);
pstmt.setInt(1, thread.getID());
ResultSet rs = pstmt.executeQuery();
rs.next();
messages = new int[rs.getInt(1)];
pstmt.close();
pstmt = con.prepareStatement(GET_MESSAGES);
pstmt.setInt(1, thread.getID());
rs = pstmt.executeQuery();
for (int i = 0; i < messages.length; i++) {
rs.next();
messages[i] = rs.getInt(1);
}
} catch (SQLException sqle) {
log.error("Error in DbThreadIterator:constructor()-" , sqle);
} finally {
try {
pstmt.close();
} catch (Exception e) {
log.error("" , e);
}
try {
con.close();
} catch (Exception e) {
log.error("" , e);
}
}
}
protected DbThreadIterator(ForumThread thread, int startIndex, int numResults) {
this.thread = thread;
int[] tempMessages = new int[numResults];
//It's very possible that there might not be as many messages to get
//as we requested. Therefore, we keep track of how many messages we
//get by keeping a messageCount.
int messageCount = 0;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(GET_MESSAGES);
pstmt.setInt(1, thread.getID());
ResultSet rs = pstmt.executeQuery();
//Move to start of index
for (int i = 0; i < startIndex; i++) {
rs.next();
}
//Now read in desired number of results
for (int i = 0; i < numResults; i++) {
if (rs.next()) {
tempMessages[messageCount] = rs.getInt("messageID");
messageCount++;
} else {
break;
}
}
} catch (SQLException sqle) {
log.error("Error in DbThreadIterator:constructor()-" , sqle);
} finally {
try {
pstmt.close();
} catch (Exception e) {
log.error("" , e);
}
try {
con.close();
} catch (Exception e) {
log.error("" , e);
}
}
messages = new int[messageCount];
for (int i = 0; i < messageCount; i++) {
messages[i] = tempMessages[i];
}
}
protected DbThreadIterator(boolean approved,ForumThread thread) {
this.thread = thread;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(MESSAGE_COUNT_APPROVED);
pstmt.setInt(1, thread.getID());
pstmt.setInt(2, approved?1:0);
ResultSet rs = pstmt.executeQuery();
rs.next();
messages = new int[rs.getInt(1)];
pstmt.close();
pstmt = con.prepareStatement(GET_MESSAGES_APPROVED);
pstmt.setInt(1, thread.getID());
pstmt.setInt(2, approved?1:0);
rs = pstmt.executeQuery();
for (int i = 0; i < messages.length; i++) {
rs.next();
messages[i] = rs.getInt(1);
}
} catch (SQLException sqle) {
log.error("Error in DbThreadIterator:constructor()-" , sqle);
} finally {
try {
pstmt.close();
} catch (Exception e) {
log.error("" , e);
}
try {
con.close();
} catch (Exception e) {
log.error("" , e);
}
}
}
protected DbThreadIterator(boolean approved,ForumThread thread, int startIndex, int numResults) {
this.thread = thread;
int[] tempMessages = new int[numResults];
//It's very possible that there might not be as many messages to get
//as we requested. Therefore, we keep track of how many messages we
//get by keeping a messageCount.
int messageCount = 0;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(GET_MESSAGES_APPROVED);
pstmt.setInt(1, thread.getID());
pstmt.setInt(2, approved?1:0);
ResultSet rs = pstmt.executeQuery();
//Move to start of index
for (int i = 0; i < startIndex; i++) {
rs.next();
}
//Now read in desired number of results
for (int i = 0; i < numResults; i++) {
if (rs.next()) {
tempMessages[messageCount] = rs.getInt("messageID");
messageCount++;
} else {
break;
}
}
} catch (SQLException sqle) {
log.error("Error in DbThreadIterator:constructor()-" , sqle);
} finally {
try {
pstmt.close();
} catch (Exception e) {
log.error("" , e);
}
try {
con.close();
} catch (Exception e) {
log.error("" , e);
}
}
messages = new int[messageCount];
for (int i = 0; i < messageCount; i++) {
messages[i] = tempMessages[i];
}
}
/**
* Returns true if there are more messages in the list.
*
* @return true if the iterator has more elements.
*/
public boolean hasNext() {
//If we are at the end of the list, there can't be any more messages
//to iterate through.
if (currentIndex + 1 >= messages.length) {
return false;
}
return true;
/*
BUG: this code calls getNextMessage() which will increment the
currentIndex variable as a result of calling this message!
//Otherwise, see if nextMessage is null. If so, try to load the next
//message to make sure it exists.
// hmm, do we really need to do this here? i think it should be left up
// to the next() method -- BL
if (nextMessage == null) {
nextMessage = getNextMessage();
if (nextMessage == null) {
return false;
}
}
return true;
*/
}
/**
* Returns the next message in the interation.
*
* @return the next message in the interation.
* @throws NoSuchElementException if the iteration has no more elements.
*/
public Object next() throws java.util.NoSuchElementException {
Message message = null;
if (nextMessage != null) {
message = nextMessage;
nextMessage = null;
} else {
message = getNextMessage();
if (message == null) {
throw new java.util.NoSuchElementException();
}
}
return message;
}
/**
* Not supported for security reasons. Use the deleteMessage method in the
* ForumThread class instead.
*
* @see ForumThread#deleteMessage(ForumMessage)
*/
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
* Returns the next available message, or null if there are no more
* messages to return.
*/
private Message getNextMessage() {
while (currentIndex + 1 < messages.length) {
currentIndex++;
try {
Message message = thread.getMessage(messages[currentIndex]);
return message;
} catch (ForumMessageNotFoundException mnfe) {
}
}
return null;
}
}