libreccm-legacy/ccm-core/src/com/arsdigita/messaging/MessageThread.java

291 lines
8.9 KiB
Java
Executable File

/*
* Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.messaging;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.kernel.Party;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.DataOperation;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.util.Assert;
import java.math.BigDecimal;
import java.util.Date;
/**
* This class abstracts the concept of a Thread of messages. I.e. it
* frees you from needing to know implementation details of the
* ThreadedMessage class.
*
* @author Kevin Scaldeferri
* @since 4.8.11
* @version $Revision: 1.5 $ $DateTime: 2004/08/16 18:10:38 $
*/
public class MessageThread extends ACSObject {
public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.messaging.Thread";
public static final String LAST_UPDATE = "lastUpdate";
private static final String ROOT = "root";
private static final String AUTHOR = "author";
private static final String REPLIES = "numReplies";
private ThreadedMessage m_root = null;
private Party m_author = null;
public MessageThread(String type) {
super(type);
}
// need some contructors here...
public MessageThread(ThreadedMessage rootMsg) {
super(BASE_DATA_OBJECT_TYPE);
setRootMessage(rootMsg);
setAuthor(rootMsg.getFrom());
setLatestUpdateDate(rootMsg.getSentDate());
}
public MessageThread(DataObject data) {
super(data);
}
public MessageThread(BigDecimal id) throws DataObjectNotFoundException {
super(new OID(BASE_DATA_OBJECT_TYPE, id));
}
public MessageThread(OID id) throws DataObjectNotFoundException {
super(id);
}
protected void initialize() {
super.initialize();
if (isNew() && get(REPLIES) == null) {
set(REPLIES, new BigDecimal(0));
}
}
/**
* This method retrieves the root message, i.e. the message that
* is the start of the thread
*/
public ThreadedMessage getRootMessage() {
if (m_root == null ) {
DataObject rootData = (DataObject) get(ROOT);
if (rootData != null) {
m_root = (ThreadedMessage)DomainObjectFactory.newInstance(rootData);
}
}
return m_root;
}
public ACSObject getContainer() {
return getRootMessage().getContainer();
}
/**
* Allow writes if user has read on the parent (forum).
*/
public void doWriteCheck() {
getContainer().assertPrivilege(PrivilegeDescriptor.READ);
}
private void setRootMessage(ThreadedMessage rootMsg) {
m_root = rootMsg;
setAssociation(ROOT, rootMsg);
}
/**
* Gets the total number of messages in this thread
*/
public long getNumReplies() {
return ((BigDecimal) get(REPLIES)).longValue();
}
/**
* Increments the number of messages in the thread by one.
* The reason for the continued existance of this is thread safety
*/
private void incrNumberOfReplies() {
DataOperation op = SessionManager
.getSession()
.retrieveDataOperation(
"com.arsdigita.messaging.incrNumReplies");
op.setParameter("threadID", getID());
op.execute();
}
/**
* Decrements the number of messages in the thread by one.
* The reason for the continued existance of this is thread safety
*/
private void decrNumberOfReplies() {
DataOperation op = SessionManager
.getSession()
.retrieveDataOperation(
"com.arsdigita.messaging.decrNumReplies");
op.setParameter("threadID", getID());
op.execute();
}
/**
* Gets the Date of the most recent message added to this thread
*/
public Date getLatestUpdateDate() {
return (Date) get(LAST_UPDATE);
}
/**
* Sets the Date of the most recent update to the thread
*/
private void setLatestUpdateDate(Date date) {
set(LAST_UPDATE, date);
}
/**
*
* @return
*/
public String getSubject() {
return getRootMessage().getSubject();
}
/**
*
* @return
*/
public String getAuthorName() {
DataObject author = (DataObject) get(AUTHOR);
if (author == null) {
return null;
} else {
return (String) author.get(DISPLAY_NAME);
}
}
/**
*
*/
public Party getAuthor() {
if (m_author == null) {
DataObject authorData = (DataObject) get(AUTHOR);
if (authorData != null) {
m_author = (Party) DomainObjectFactory.newInstance(authorData);
}
}
return m_author;
}
/**
*
* @param author
*/
private void setAuthor(Party author) {
m_author = author;
setAssociation(AUTHOR, author);
}
/**
* @deprecated ThreadedMessage now updates thread statistics after save
* and after delete
* updates the MessageThread as necessary for the new Message being added.
* This is only meant to be called by the ThreadedMessage class
*
* @pre msg.getThread().equals(this)
*/
void updateForNewMessage(ThreadedMessage msg) {
Assert.isTrue(msg.getThread().equals(this));
setLatestUpdateDate(msg.getSentDate());
incrNumberOfReplies();
}
/**
* @deprecated ThreadedMessage now updates thread statistics after save
* and after delete
* updates the MessageThread as necessary for a Message being removed.
* This is only meant to be called by the ThreadedMessage class
*
* @pre msg.getThread().equals(this)
*/
void removeMessage(ThreadedMessage msg) {
Assert.isTrue(msg.getThread().equals(this));
decrNumberOfReplies();
}
/**
* retrieves the MessageThread object which has the specified
* ThreadedMessage as its root
*
* @pre msg.getRoot == null
*/
public static MessageThread getFromRootMessage(ThreadedMessage msg) {
Assert.assertEquals(null, msg.getRoot());
DataCollection threads = SessionManager.getSession().retrieve(
BASE_DATA_OBJECT_TYPE);
threads.addEqualsFilter("root.id", msg.getID());
MessageThread t = null;
try {
if (threads.next()) {
t = new MessageThread(threads.getDataObject());
} else {
// we would probably like to do something graceful here
// in general, but for now we let it return null so
// we make sure that our data migration script works
}
} finally {
threads.close();
}
return t;
}
public String toString() {
return getOID().toString();
}
/**
* update reply count and last updated date according to
* current database contents. subclasses of ThreadedMessage
* may inplement addReplyFilter to filter out any messages
* that shouldn't be
* @param message
*/
public void updateThreadStatistics(ThreadedMessage message) {
DataCollection replies = SessionManager.getSession().retrieve(message.getObjectType());
replies.addEqualsFilter(ThreadedMessage.ROOT, getRootMessage().getID());
message.addReplyFilter(replies);
long replyCount = replies.size();
set(REPLIES, new BigDecimal(replyCount));
if (replyCount == 0){
setLatestUpdateDate(this.getRootMessage().getSentDate());
} else {
replies.addOrder(Message.SENT + " desc");
if(replies.next()){
ThreadedMessage latestReply = (ThreadedMessage) DomainObjectFactory.newInstance(replies.getDataObject());
setLatestUpdateDate(latestReply.getSentDate());
replies.close();
}
}
}
}