,
+ * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
+ * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
+ *
+ * Contributor(s):
+ */
+package com.silverwrist.venice.core.impl;
+
+import java.sql.*;
+import java.util.*;
+import org.apache.log4j.*;
+import com.silverwrist.venice.core.*;
+import com.silverwrist.venice.core.internals.EnvEngine;
+import com.silverwrist.venice.db.*;
+import com.silverwrist.venice.except.*;
+import com.silverwrist.venice.htmlcheck.HTMLChecker;
+
+class PublishedMessageTopicImpl implements TopicContext
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Category logger = Category.getInstance(PublishedMessageTopicImpl.class);
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private EnvEngine env;
+ private int cid;
+ private int topicid;
+ private short topicnum;
+ private int creator_uid;
+ private int total_msgs;
+ private boolean frozen;
+ private boolean archived;
+ private java.util.Date createdate;
+ private java.util.Date lastupdate;
+ private String name;
+ private String postlink;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ PublishedMessageTopicImpl(EnvEngine env, int cid, int topicid) throws DataException
+ {
+ Connection conn = null;
+ try
+ { // get a database connection
+ conn = env.getConnection();
+ Statement stmt = conn.createStatement();
+
+ // query the topics table for information
+ StringBuffer sql =
+ new StringBuffer("SELECT confid, num, creator_uid, top_message, frozen, archived, createdate, "
+ + "lastupdate, name FROM topics WHERE topicid = ");
+ sql.append(topicid).append(";");
+ ResultSet rs = stmt.executeQuery(sql.toString());
+ if (!(rs.next()))
+ throw new DataException("Topic with ID " + topicid + " not found");
+
+ // fill internal attributes with data
+ this.env = env;
+ this.cid = cid;
+ this.topicid = topicid;
+ int confid = rs.getInt(1);
+ this.topicnum = rs.getShort(2);
+ this.creator_uid = rs.getInt(3);
+ this.total_msgs = rs.getInt(4) + 1;
+ this.frozen = rs.getBoolean(5);
+ this.archived = rs.getBoolean(6);
+ this.createdate = SQLUtil.getFullDateTime(rs,7);
+ this.lastupdate = SQLUtil.getFullDateTime(rs,8);
+ this.name = rs.getString(9);
+
+ // retrieve the community alias
+ rs = stmt.executeQuery("SELECT alias FROM sigs WHERE sigid = " + cid + ";");
+ if (!(rs.next()))
+ throw new DataException("Community with ID " + cid + " not found");
+ postlink = rs.getString(1) + "!";
+
+ // retrieve a conference alias
+ rs = stmt.executeQuery("SELECT alias FROM confalias WHERE confid = " + confid + " LIMIT 1;");
+ if (!(rs.next()))
+ throw new DataException("Conference with ID " + confid + " not found");
+ postlink += (rs.getString(1) + "." + topicnum);
+
+ } // end try
+ catch (SQLException e)
+ { // turn this into a data exception
+ logger.error("unable to get topic data",e);
+ throw new DataException("Error getting topic data: " + e.getMessage(),e);
+
+ } // end catch
+ finally
+ { // release the connection
+ env.releaseConnection(conn);
+
+ } // end finally
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface TopicContext
+ *--------------------------------------------------------------------------------
+ */
+
+ public void refresh()
+ { // do nothing
+ } // end refresh
+
+ public int getTopicID()
+ {
+ return topicid;
+
+ } // end getTopicID
+
+ public short getTopicNumber()
+ {
+ return topicnum;
+
+ } // end getTopicNumber
+
+ public String getName()
+ {
+ return name;
+
+ } // end getName
+
+ public int getUnreadMessages()
+ {
+ return 0;
+
+ } // end getUnreadMessages
+
+ public int getTotalMessages()
+ {
+ return total_msgs;
+
+ } // end getTotalMessages
+
+ public java.util.Date getLastUpdateDate()
+ {
+ return lastupdate;
+
+ } // end getLastUpdateDate
+
+ public int getCreatorUID()
+ {
+ return creator_uid;
+
+ } // end getCreatorUID
+
+ public boolean isFrozen()
+ {
+ return frozen;
+
+ } // end isFrozen
+
+ public boolean isArchived()
+ {
+ return archived;
+
+ } // end isArchived
+
+ public java.util.Date getCreatedDate()
+ {
+ return createdate;
+
+ } // end egtCreatedDate
+
+ public boolean isHidden()
+ {
+ return false;
+
+ } // end isHidden
+
+ public boolean isDeleted()
+ {
+ return false;
+
+ } // end isDeleted
+
+ public boolean canFreeze()
+ {
+ return false;
+
+ } // end canFreeze
+
+ public boolean canArchive()
+ {
+ return false;
+
+ } // end canArchive
+
+ public void setFrozen(boolean flag) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end setFrozen
+
+ public void setArchived(boolean flag) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end setArchived
+
+ public void setHidden(boolean flag)
+ { // do nothing
+ } // end setHidden
+
+ public int getFirstUnreadMessage()
+ {
+ return -1;
+
+ } // end getFirstUnreadMessage
+
+ public void setUnreadMessages(int count)
+ { // do nothing
+ } // end setUnreadMessages
+
+ public void fixSeen()
+ { // do nothing
+ } // end fixSeen
+
+ public List getMessages(int low, int high) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end getMessages
+
+ public TopicMessageContext getMessage(int number) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end getMessage
+
+ public TopicMessageContext postNewMessage(long parent, String pseud, String text) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end postNewMessage
+
+ public HTMLChecker getPreviewChecker()
+ {
+ return null;
+
+ } // end getPreviewChecker
+
+ public boolean canDelete()
+ {
+ return false;
+
+ } // end canDelete
+
+ public void delete() throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end delete
+
+ public void deleteTopic() throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end deleteTopic
+
+ public List getActivePosters(int skip, int limit) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end getActivePosters
+
+ public List getActivePosters(int limit) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end getActivePosters
+
+ public List getActivePosters() throws DataException, AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end getActivePosters
+
+ public List getActiveReaders(int skip, int limit) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end getActiveReaders
+
+ public List getActiveReaders(int limit) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end getActiveReaders
+
+ public List getActiveReaders() throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end getActiveReaders
+
+ public boolean isBozo(int other_uid)
+ {
+ return false;
+
+ } // end isBozo
+
+ public void setBozo(int other_uid, boolean bozo)
+ { // do nothing
+ } // end setBozo
+
+ public boolean canSetBozo(int other_uid)
+ {
+ return false;
+
+ } // end canSetBozo
+
+ public List getBozos()
+ {
+ return Collections.EMPTY_LIST;
+
+ } // end getBozos
+
+ public boolean isSubscribed()
+ {
+ return false;
+
+ } // end isSubscribed
+
+ public void setSubscribed(boolean flag)
+ { // do nothing
+ } // end setSubscribed
+
+ public void sendInvitation(String address, String personal_message) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end sendInvitation
+
+ public boolean canSendInvitation()
+ {
+ return false;
+
+ } // end canSendInvitation
+
+ public void sendMailToParticipants(boolean posters, int day_limit, String subject, String text)
+ throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end sendMailToParticipants
+
+ public List searchPosts(String search_terms, int offset, int count)
+ throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end searchPosts
+
+ public int getSearchPostCount(String search_terms) throws AccessError
+ {
+ throw new AccessError("cannot perform this function from a read-only topic view");
+
+ } // end getSearchPostCount
+
+ public ConferenceContext getEnclosingConference()
+ {
+ throw new InternalStateError("function not implemented");
+
+ } // end getEnclosingConference
+
+ public String getPostLink()
+ {
+ return postlink;
+
+ } // end getPostLink
+
+} // end PublishedMessageTopicImpl
diff --git a/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java b/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java
index c4b18b1..447082d 100644
--- a/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java
+++ b/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java
@@ -49,6 +49,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
private EnvConference env; // the conference environment
private long postid; // the ID of this post
private long parent; // the parent post ID (not really used)
+ private int topicid; // the topic ID we live within
private int num; // the post number within the topic
private int linecount; // number of lines in message
private int creator_uid; // the UID of the poster
@@ -70,14 +71,15 @@ class TopicMessageUserContextImpl implements TopicMessageContext
*--------------------------------------------------------------------------------
*/
- protected TopicMessageUserContextImpl(EnvConference env, long postid, long parent, int num, int linecount,
- int creator_uid, java.util.Date posted, boolean hidden,
+ protected TopicMessageUserContextImpl(EnvConference env, long postid, long parent, int topicid, int num,
+ int linecount, int creator_uid, java.util.Date posted, boolean hidden,
int scribble_uid, java.util.Date scribble_date, String pseud,
int datalen, String filename, String mimetype, int stgmethod)
{
this.env = env;
this.postid = postid;
this.parent = parent;
+ this.topicid = topicid;
this.num = num;
this.linecount = linecount;
this.creator_uid = creator_uid;
@@ -93,12 +95,13 @@ class TopicMessageUserContextImpl implements TopicMessageContext
} // end constructor
- TopicMessageUserContextImpl(EnvConference env, long postid, long parent, int num, int linecount,
+ TopicMessageUserContextImpl(EnvConference env, long postid, long parent, int topicid, int num, int linecount,
int creator_uid, java.util.Date posted, String pseud)
{
this.env = env;
this.postid = postid;
this.parent = parent;
+ this.topicid = topicid;
this.num = num;
this.linecount = linecount;
this.creator_uid = creator_uid;
@@ -1007,8 +1010,9 @@ class TopicMessageUserContextImpl implements TopicMessageContext
ar = env.newAudit(AuditRecord.PUBLISH_POST,"conf=" + env.getConfID() + ",post=" + postid);
// establish cached data object for front page
- env.getEngine().publishNew(new PublishedMessageImpl(env,postid,parent,num,linecount,creator_uid,
- posted,pseud,creator_cache,text_cache));
+ env.getEngine().publishNew(new PublishedMessageImpl(env,env.getCommunityID(),postid,parent,topicid,
+ num,linecount,creator_uid,posted,pseud,
+ creator_cache,text_cache));
done = true;
} // end try
@@ -1035,6 +1039,48 @@ class TopicMessageUserContextImpl implements TopicMessageContext
} // end publish
+ public TopicContext getEnclosingTopic() throws DataException
+ {
+ return TopicUserContextImpl.getTopicByID(env,topicid);
+
+ } // end getEnclosingTopic
+
+ public String getPostLink() throws DataException
+ {
+ if (nuked)
+ return null;
+ String prefix = env.getConference().selfConference().getPostLink();
+ short topicnum = -1;
+ Connection conn = null;
+
+ try
+ { // get a database connection
+ conn = env.getConnection();
+ Statement stmt = conn.createStatement();
+
+ ResultSet rs = stmt.executeQuery("SELECT num FROM topics WHERE topicid = " + topicid + ";");
+ if (!(rs.next()))
+ throw new DataException("unable to locate topic number for topic ID " + topicid);
+ topicnum = rs.getShort(1);
+
+ } // end try
+ catch (SQLException e)
+ { // just trap SQL exceptions and log them
+ logger.error("unable to get topic number: " + e.getMessage(),e);
+ throw new DataException("unable to get topic number: " + e.getMessage(),e);
+
+ } // end catch
+ finally
+ { // make sure we release the connection before we go
+ env.releaseConnection(conn);
+
+ } // end finally
+
+ // composite together the post link value
+ return prefix + "." + topicnum + "." + num;
+
+ } // end getPostLink
+
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
@@ -1070,7 +1116,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
while (rs.next())
{ // create implementation objects and shove them into the return vector
TopicMessageContext val =
- new TopicMessageUserContextImpl(env,rs.getLong(1),rs.getLong(2),rs.getInt(3),rs.getInt(4),
+ new TopicMessageUserContextImpl(env,rs.getLong(1),rs.getLong(2),topicid,rs.getInt(3),rs.getInt(4),
rs.getInt(5),SQLUtil.getFullDateTime(rs,6),rs.getBoolean(7),
rs.getInt(8),SQLUtil.getFullDateTime(rs,9),rs.getString(10),
rs.getInt(11),rs.getString(12),rs.getString(13),rs.getInt(14));
@@ -1120,10 +1166,11 @@ class TopicMessageUserContextImpl implements TopicMessageContext
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next()) // create an object reference and return it
- return new TopicMessageUserContextImpl(env,rs.getLong(1),rs.getLong(2),rs.getInt(3),rs.getInt(4),
- rs.getInt(5),SQLUtil.getFullDateTime(rs,6),rs.getBoolean(7),
- rs.getInt(8),SQLUtil.getFullDateTime(rs,9),rs.getString(10),
- rs.getInt(11),rs.getString(12),rs.getString(13),rs.getInt(14));
+ return new TopicMessageUserContextImpl(env,rs.getLong(1),rs.getLong(2),topicid,rs.getInt(3),
+ rs.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6),
+ rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9),
+ rs.getString(10),rs.getInt(11),rs.getString(12),
+ rs.getString(13),rs.getInt(14));
// indicates an error...
throw new DataException("Message not found.");
@@ -1156,10 +1203,11 @@ class TopicMessageUserContextImpl implements TopicMessageContext
Statement stmt = conn.createStatement();
StringBuffer sql =
- new StringBuffer("SELECT p.postid, p.parent, p.num, p.linecount, p.creator_uid, p.posted, "
- + "p.hidden, p.scribble_uid, p.scribble_date, p.pseud, a.datalen, a.filename, "
- + "a.mimetype, a.stgmethod FROM topics t, posts p LEFT JOIN postattach a "
- + "ON p.postid = a.postid WHERE t.topicid = p.topicid AND t.confid = ");
+ new StringBuffer("SELECT p.postid, p.parent, p.topicid, p.num, p.linecount, p.creator_uid, "
+ + "p.posted, p.hidden, p.scribble_uid, p.scribble_date, p.pseud, a.datalen, "
+ + "a.filename, a.mimetype, a.stgmethod FROM topics t, posts p LEFT JOIN "
+ + "postattach a ON p.postid = a.postid WHERE t.topicid = p.topicid AND "
+ + "t.confid = ");
sql.append(env.getConfID()).append(" AND p.postid = ").append(postid).append(';');
if (logger.isDebugEnabled())
logger.debug("SQL: " + sql.toString());
@@ -1167,9 +1215,10 @@ class TopicMessageUserContextImpl implements TopicMessageContext
if (rs.next()) // create an object reference and return it
return new TopicMessageUserContextImpl(env,rs.getLong(1),rs.getLong(2),rs.getInt(3),rs.getInt(4),
- rs.getInt(5),SQLUtil.getFullDateTime(rs,6),rs.getBoolean(7),
- rs.getInt(8),SQLUtil.getFullDateTime(rs,9),rs.getString(10),
- rs.getInt(11),rs.getString(12),rs.getString(13),rs.getInt(14));
+ rs.getInt(5),rs.getInt(6),SQLUtil.getFullDateTime(rs,7),
+ rs.getBoolean(8),rs.getInt(9),SQLUtil.getFullDateTime(rs,10),
+ rs.getString(11),rs.getInt(12),rs.getString(13),
+ rs.getString(14),rs.getInt(15));
// indicates an error...
throw new DataException("Message not found.");
diff --git a/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java b/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java
index fff8580..f773f41 100644
--- a/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java
+++ b/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java
@@ -850,8 +850,8 @@ class TopicUserContextImpl implements TopicContext
// else don't bother - it would be a waste of time
// return the new message context
- return new TopicMessageUserContextImpl(env,new_post_id,parent,new_post_num,text_linecount,env.getUserID(),
- posted_date,real_pseud);
+ return new TopicMessageUserContextImpl(env,new_post_id,parent,topicid,new_post_num,text_linecount,
+ env.getUserID(),posted_date,real_pseud);
} // end postMessage
@@ -1516,6 +1516,20 @@ class TopicUserContextImpl implements TopicContext
} // end getSearchPostCount
+ public ConferenceContext getEnclosingConference()
+ {
+ return env.getConference().selfConference();
+
+ } // end getEnclosingConference
+
+ public String getPostLink() throws DataException
+ {
+ if (deleted)
+ return null;
+ return env.getConference().selfConference().getPostLink() + "." + topicnum;
+
+ } // end getPostLink
+
/*--------------------------------------------------------------------------------
* External operations usable only from within the package
*--------------------------------------------------------------------------------
diff --git a/src/com/silverwrist/venice/core/internals/ConferenceBackend.java b/src/com/silverwrist/venice/core/internals/ConferenceBackend.java
index 6e2a360..34c8962 100644
--- a/src/com/silverwrist/venice/core/internals/ConferenceBackend.java
+++ b/src/com/silverwrist/venice/core/internals/ConferenceBackend.java
@@ -20,11 +20,14 @@ package com.silverwrist.venice.core.internals;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
+import com.silverwrist.venice.core.ConferenceContext;
import com.silverwrist.venice.db.PostLinkDecoderContext;
import com.silverwrist.venice.except.DataException;
public interface ConferenceBackend
{
+ public abstract ConferenceContext selfConference();
+
public abstract int realConfID();
public abstract boolean userCanHide();
diff --git a/src/com/silverwrist/venice/servlets/PostShortcut.java b/src/com/silverwrist/venice/servlets/PostShortcut.java
index 79984c3..e599655 100644
--- a/src/com/silverwrist/venice/servlets/PostShortcut.java
+++ b/src/com/silverwrist/venice/servlets/PostShortcut.java
@@ -98,7 +98,10 @@ public class PostShortcut extends VeniceServlet
} // end catch
catch (AccessError ae)
{ // we can't get to the conference...
- return new ErrorBox("Access Error",ae.getMessage(),null);
+ if (user.isLoggedIn())
+ return new ErrorBox("Access Error",ae.getMessage(),null);
+ else
+ return new LogInOrCreate("go/" + raw_link);
} // end catch
@@ -122,7 +125,10 @@ public class PostShortcut extends VeniceServlet
} // end catch
catch (AccessError ae)
{ // we can't get to the topic...
- return new ErrorBox("Access Error",ae.getMessage(),null);
+ if (user.isLoggedIn())
+ return new ErrorBox("Access Error",ae.getMessage(),null);
+ else
+ return new LogInOrCreate("go/" + raw_link);
} // end catch
diff --git a/src/com/silverwrist/venice/servlets/format/TopDisplay.java b/src/com/silverwrist/venice/servlets/format/TopDisplay.java
index f1438d6..99ceb65 100644
--- a/src/com/silverwrist/venice/servlets/format/TopDisplay.java
+++ b/src/com/silverwrist/venice/servlets/format/TopDisplay.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
+import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
@@ -33,6 +34,8 @@ public class TopDisplay implements ContentRender, ColorSelectors
*--------------------------------------------------------------------------------
*/
+ private static Category logger = Category.getInstance(TopDisplay.class);
+
private static final String ATTR_NAME = "com.silverwrist.venice.TopDisplay";
/*--------------------------------------------------------------------------------
@@ -125,6 +128,7 @@ public class TopDisplay implements ContentRender, ColorSelectors
} // end try
catch (ServletException se)
{ // since we can't throw ServletException, we throw IOException
+ logger.error("top_content.jsp failure",se);
throw new IOException("Failure including top_content.jsp");
} // end catch
@@ -162,7 +166,8 @@ public class TopDisplay implements ContentRender, ColorSelectors
} // end try
catch (ServletException se)
- { // since we can't throw ServletException, we throw IOException
+ { // since we can't throw ServletException, we write an error message
+ logger.error("sidebox #" + i + " failure",se);
out.write(rdat.getStdFontTag(SIDEBOX_CONTENT_FOREGROUND,2) + "failure rendering class "
+ sideboxes[i].getClass().getName() + ": " + StringUtil.encodeHTML(se.getMessage())
+ "\n");
@@ -173,9 +178,13 @@ public class TopDisplay implements ContentRender, ColorSelectors
rdat.flushOutput(); // now make sure the included page is properly flushed
} // end else if
- else // this is bogus - just display a little error here
+ else
+ { // this is bogus - just display a little error here
+ logger.error("sidebox #" + i + " class " + sideboxes[i].getClass().getName() + " cannot be rendered");
out.write(rdat.getStdFontTag(SIDEBOX_CONTENT_FOREGROUND,2) + "cannot display sidebox of class: "
+ sideboxes[i].getClass().getName() + "\n");
+
+ } // end else
// close up the framework of this sidebox
out.write("\n");
@@ -215,6 +224,29 @@ public class TopDisplay implements ContentRender, ColorSelectors
} // end getPosterName
+ public static String getTopicPostLink(RenderData rdat, TopicMessageContext msg)
+ {
+ try
+ { // retrieve the topic post link and name, and combine them
+ TopicContext topic = msg.getEnclosingTopic();
+ String plink = topic.getPostLink();
+ return "" + topic.getName() + "";
+
+ } // end try
+ catch (DataException de)
+ { // just return null on failure
+ return null;
+
+ } // end catch
+ catch (Exception e)
+ { // temporary guard point here
+ logger.error("Caught in getTopicPostLink:",e);
+ return null;
+
+ } // end catch
+
+ } // end getTopicPostLink
+
public static String getMessageBodyText(TopicMessageContext msg)
{
try
diff --git a/web/format/top_content.jsp b/web/format/top_content.jsp
index 4cec90e..0da0922 100644
--- a/web/format/top_content.jsp
+++ b/web/format/top_content.jsp
@@ -37,6 +37,7 @@
for (int i=0; i
<% if (i>0) { %>
<% } %>
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
@@ -47,6 +48,9 @@
)
<%= rdat.rewritePostData(data.getMessageBodyText(msg)) %>
+ <% if (topic_link!=null) { %>
+ (From the topic: <%= topic_link %>)
+ <% } // end if %>
<%
} // end for