added customizable "HTML Escapes" for the top and bottom of the topic list

and post list pages; configurable through the host tools
This commit is contained in:
Eric J. Bowersox 2001-12-05 00:03:39 +00:00
parent 9cc34facf6
commit 9d34cc35f0
17 changed files with 699 additions and 58 deletions

View File

@ -310,6 +310,14 @@ CREATE TABLE propconf (
PRIMARY KEY (confid, ndx) PRIMARY KEY (confid, ndx)
); );
# The conference custom HTML block table. There are two custom blocks, one at the
# top of the page, one at the bottom, each a maximum of 64K in length.
CREATE TABLE confcustom (
confid INT NOT NULL PRIMARY KEY,
htmltop TEXT,
htmlbottom TEXT
);
# The table describing topics within a conference. # The table describing topics within a conference.
CREATE TABLE topics ( CREATE TABLE topics (
topicid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, topicid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,

View File

@ -40,6 +40,9 @@ public interface ConferenceContext
public static final int SORT_TOTAL = 4; public static final int SORT_TOTAL = 4;
public static final int SORT_DATE = 5; public static final int SORT_DATE = 5;
public static final int CUST_BLOCK_TOP = 0;
public static final int CUST_BLOCK_BOTTOM = 1;
public abstract int getConfID(); public abstract int getConfID();
public abstract String getName(); public abstract String getName();
@ -174,4 +177,10 @@ public interface ConferenceContext
public abstract void sendMailToParticipants(boolean posters, int day_limit, String subject, String text) public abstract void sendMailToParticipants(boolean posters, int day_limit, String subject, String text)
throws AccessError, DataException; throws AccessError, DataException;
public abstract String getCustomBlock(int selector) throws DataException;
public abstract void setCustomBlock(int selector, String data) throws AccessError, DataException;
public abstract void removeCustomBlocks() throws AccessError, DataException;
} // end interface ConferenceContext } // end interface ConferenceContext

View File

@ -129,6 +129,7 @@ class BackgroundCommunityPurge implements Runnable
stmt.executeUpdate("DELETE FROM confs WHERE confid = " + key + ";"); stmt.executeUpdate("DELETE FROM confs WHERE confid = " + key + ";");
stmt.executeUpdate("DELETE FROM confalias WHERE confid = " + key + ";"); stmt.executeUpdate("DELETE FROM confalias WHERE confid = " + key + ";");
stmt.executeUpdate("DELETE FROM propconf WHERE confid = " + key + ";"); stmt.executeUpdate("DELETE FROM propconf WHERE confid = " + key + ";");
stmt.executeUpdate("DELETE FROM confcustom WHERE confid = " + key + ";");
// determine the number of topics in this conference, and the maximum topic ID, and use // determine the number of topics in this conference, and the maximum topic ID, and use
// that information to queue up the conference deletion // that information to queue up the conference deletion

View File

@ -80,6 +80,7 @@ class BackgroundConferencePurge implements Runnable
stmt.executeUpdate("DELETE FROM confsettings WHERE confid = " + confid + ";"); stmt.executeUpdate("DELETE FROM confsettings WHERE confid = " + confid + ";");
stmt.executeUpdate("DELETE FROM confhotlist WHERE confid = " + confid + ";"); stmt.executeUpdate("DELETE FROM confhotlist WHERE confid = " + confid + ";");
stmt.executeUpdate("DELETE FROM propconf WHERE confid = " + confid + ";"); stmt.executeUpdate("DELETE FROM propconf WHERE confid = " + confid + ";");
stmt.executeUpdate("DELETE FROM confcustom WHERE confid = " + confid + ";");
// look up all the topic IDs that are present in this conference // look up all the topic IDs that are present in this conference
int[] topicids = new int[num_topics]; int[] topicids = new int[num_topics];

View File

@ -772,4 +772,22 @@ class ConferenceCommunityContextImpl implements ConferenceCommunityContext
} // end setProperties } // end setProperties
public String getCustomBlock(int selector) throws DataException
{
return getConferenceData().getCustomBlock(selector);
} // end getCustomBlock
public void setCustomBlock(int selector, String data) throws DataException
{
getConferenceData().setCustomBlock(selector,data);
} // end setCustomBlock
public void removeCustomBlocks() throws DataException
{
getConferenceData().removeCustomBlocks();
} // end removeCustomBlocks
} // end class ConferenceCommunityContextImpl } // end class ConferenceCommunityContextImpl

View File

@ -17,6 +17,7 @@
*/ */
package com.silverwrist.venice.core.impl; package com.silverwrist.venice.core.impl;
import java.lang.ref.*;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.*;
import org.apache.log4j.*; import org.apache.log4j.*;
@ -67,6 +68,9 @@ class ConferenceCoreData implements ConferenceData
private boolean creating_topic = false; // is somebody creating a topic? private boolean creating_topic = false; // is somebody creating a topic?
private boolean deleted = false; // has this conference been deleted? private boolean deleted = false; // has this conference been deleted?
private OptionSet flags; // option flags private OptionSet flags; // option flags
private boolean has_custom = false; // do we have custom blocks?
private SoftReference cust_top = null; // custom block for top
private SoftReference cust_bottom = null; // custom block for bottom
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructors * Constructors
@ -97,6 +101,7 @@ class ConferenceCoreData implements ConferenceData
loadData(rs); // load the conference data loadData(rs); // load the conference data
flags = new OptionSet(); flags = new OptionSet();
loadProperties(conn); loadProperties(conn);
loadCustom(conn);
} // end try } // end try
catch (SQLException e) catch (SQLException e)
@ -185,6 +190,36 @@ class ConferenceCoreData implements ConferenceData
} // end loadProperties } // end loadProperties
private synchronized void loadCustom(Connection conn) throws SQLException
{
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("SELECT htmltop, htmlbottom FROM confcustom WHERE confid = ");
sql.append(confid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next())
{ // load the custom data and save it as SoftReferences (so it can be erased
has_custom = true;
String s;
if ((cust_top==null) || (cust_top.get()==null))
{ // retrieve the top custom block
s = rs.getString(1);
if (s!=null)
cust_top = new SoftReference(s);
} // end if
if ((cust_bottom==null) || (cust_bottom.get()==null))
{ // retrieve the bottom custom block
s = rs.getString(2);
if (s!=null)
cust_bottom = new SoftReference(s);
} // end if
} // end if
} // end loadCustom
private synchronized void touchUpdate(Connection conn) throws SQLException private synchronized void touchUpdate(Connection conn) throws SQLException
{ {
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
@ -1269,6 +1304,160 @@ class ConferenceCoreData implements ConferenceData
} // end setProperties } // end setProperties
public String getCustomBlock(int selector) throws DataException
{
SoftReference r;
if (selector==ConferenceContext.CUST_BLOCK_TOP)
r = cust_top;
else if (selector==ConferenceContext.CUST_BLOCK_BOTTOM)
r = cust_bottom;
else
throw new IndexOutOfBoundsException("invalid custom block selector");
if ((!has_custom) || (r==null))
return null; // no custom block to return
// try to retrieve a custom block value
String rc = (String)(r.get());
if (rc==null)
{ // need to reload the custom block data
Connection conn = null;
try
{ // load the custom information
conn = env.getConnection();
loadCustom(conn);
// set up the return value
if (selector==ConferenceContext.CUST_BLOCK_TOP)
rc = (String)(cust_top.get());
else if (selector==ConferenceContext.CUST_BLOCK_BOTTOM)
rc = (String)(cust_bottom.get());
} // end try
catch (SQLException e)
{ // database error - this is a DataException
logger.error("DB error getting custom block: " + e.getMessage(),e);
throw new DataException("unable to get custom block: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
env.releaseConnection(conn);
} // end finally
} // end if
return rc;
} // end getCustomBlock
public synchronized void setCustomBlock(int selector, String data) throws DataException
{
if (logger.isDebugEnabled())
logger.debug("setCustomBlock(" + selector + ") entry");
String fieldname;
if (selector==ConferenceContext.CUST_BLOCK_TOP)
fieldname = "htmltop";
else if (selector==ConferenceContext.CUST_BLOCK_BOTTOM)
fieldname = "htmlbottom";
else
throw new IndexOutOfBoundsException("invalid custom block selector");
Connection conn = null;
try
{ // get a connection
conn = env.getConnection();
Statement stmt = conn.createStatement();
// build the right SQL command
StringBuffer sql = null;
if (has_custom)
{ // build an UPDATE command
sql = new StringBuffer("UPDATE confcustom SET ");
sql.append(fieldname).append(" = ").append(SQLUtil.encodeStringArg(data)).append(" WHERE confid = ");
sql.append(confid).append(';');
} // end if
else
{ // build an INSERT command
sql = new StringBuffer("INSERT INTO confcustom (confid, ");
sql.append(fieldname).append(") VALUES (").append(confid).append(", ");
sql.append(SQLUtil.encodeStringArg(data)).append(");");
} // end else
stmt.executeUpdate(sql.toString()); // update the database
// save off all the data cached locally
has_custom = true;
SoftReference old_r = null;
if (selector==ConferenceContext.CUST_BLOCK_TOP)
{ // replace the top block
old_r = cust_top;
cust_top = new SoftReference(data);
} // end if
else if (selector==ConferenceContext.CUST_BLOCK_BOTTOM)
{ // replace the bottom block
old_r = cust_bottom;
cust_bottom = new SoftReference(data);
} // end else if
if (old_r!=null)
old_r.clear(); // dump the old data block before we go
} // end try
catch (SQLException e)
{ // database error - this is a DataException
logger.error("DB error setting custom block: " + e.getMessage(),e);
throw new DataException("unable to set custom block: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
env.releaseConnection(conn);
} // end finally
} // end setCustomBlock
public synchronized void removeCustomBlocks() throws DataException
{
Connection conn = null;
try
{ // get a connection
conn = env.getConnection();
Statement stmt = conn.createStatement();
// execute the delete statement
stmt.executeUpdate("DELETE FROM confcustom WHERE confid = " + confid + ";");
// zap the custom data in this object
has_custom = false;
if (cust_top!=null)
cust_top.clear();
if (cust_bottom!=null)
cust_bottom.clear();
cust_top = cust_bottom = null;
} // end try
catch (SQLException e)
{ // database error - this is a DataException
logger.error("DB error removing custom blocks: " + e.getMessage(),e);
throw new DataException("unable to remove custom blocks: " + e.getMessage(),e);
} // end catch
finally
{ // make sure the connection is released before we go
env.releaseConnection(conn);
} // end finally
} // end removeCustomBlocks
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* External static operations (usable only from within package) * External static operations (usable only from within package)
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -1591,6 +1591,40 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end if } // end if
public String getCustomBlock(int selector) throws DataException
{
return getConferenceData().getCustomBlock(selector);
} // end getCustomBlock
public void setCustomBlock(int selector, String data) throws AccessError, DataException
{
if (!(getConferenceData().canChangeConference(level)))
{ // this user can't modify the conference properties
logger.error("setCustomBlock(): user not permitted to change custom blocks");
throw new AccessError("You are not permitted to change the custom blocks for this conference.");
} // end if
// call down to set the custom block
getConferenceData().setCustomBlock(selector,data);
} // end setCustomBlock
public void removeCustomBlocks() throws AccessError, DataException
{
if (!(getConferenceData().canChangeConference(level)))
{ // this user can't modify the conference properties
logger.error("setCustomBlock(): user not permitted to change custom blocks");
throw new AccessError("You are not permitted to change the custom blocks for this conference.");
} // end if
// call down to remove the custom blocks
getConferenceData().removeCustomBlocks();
} // end removeCustomBlocks
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Implementations from interface ConferenceBackend * Implementations from interface ConferenceBackend
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -115,4 +115,10 @@ public interface ConferenceCommunityContext
public abstract void setProperties(ConferenceProperties props) throws DataException; public abstract void setProperties(ConferenceProperties props) throws DataException;
public abstract String getCustomBlock(int selector) throws DataException;
public abstract void setCustomBlock(int selector, String data) throws DataException;
public abstract void removeCustomBlocks() throws DataException;
} // end interface ConferenceCommunityContext } // end interface ConferenceCommunityContext

View File

@ -109,4 +109,10 @@ public interface ConferenceData
public abstract void setProperties(ConferenceProperties props) throws DataException; public abstract void setProperties(ConferenceProperties props) throws DataException;
public abstract String getCustomBlock(int selector) throws DataException;
public abstract void setCustomBlock(int selector, String data) throws DataException;
public abstract void removeCustomBlocks() throws DataException;
} // end interface ConferenceData } // end interface ConferenceData

View File

@ -168,6 +168,8 @@ public class ConfOperations extends VeniceServlet
* SH = Hide/show conference from sequence manager menu * SH = Hide/show conference from sequence manager menu
* SS = Change conference sequence from sequence manager menu * SS = Change conference sequence from sequence manager menu
* T = Create topic (requires conference parameter) * T = Create topic (requires conference parameter)
* U = Customize Conference Display (requires conference parameter)
* UX = Remove all custom blocks (requires conference parameter)
* Other = Display list of conferences in community * Other = Display list of conferences in community
*/ */
@ -337,8 +339,8 @@ public class ConfOperations extends VeniceServlet
String message = "You are about to permanently delete the \"" + conf.getName() + "\" conference! " String message = "You are about to permanently delete the \"" + conf.getName() + "\" conference! "
+ "Are you sure you want to do this?"; + "Are you sure you want to do this?";
return new ConfirmBox(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM,"Delete Conference",message, return new ConfirmBox(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM,"Delete Conference",message,
"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=SDEL", "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID()
on_error); + "&cmd=SDEL",on_error);
} // end else } // end else
@ -495,7 +497,8 @@ public class ConfOperations extends VeniceServlet
try try
{ // display the "Conference Reports" display { // display the "Conference Reports" display
setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=QR"); setMyLocation(request,"confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID()
+ "&cmd=QR");
return new ReportConferenceMenu(comm,conf); return new ReportConferenceMenu(comm,conf);
} // end try } // end try
@ -602,7 +605,7 @@ public class ConfOperations extends VeniceServlet
} // end try } // end try
catch (DataException de) catch (DataException de)
{ // something wrong in the database { // something wrong in the database
return new ErrorBox("Database Error","Database error getting topic list " + de.getMessage(), return new ErrorBox("Database Error","Database error getting topic list: " + de.getMessage(),
on_error); on_error);
} // end catch } // end catch
@ -614,6 +617,61 @@ public class ConfOperations extends VeniceServlet
} // end if ("I" command) } // end if ("I" command)
if (cmd.equals("U"))
{ // "U" = Customize Conference Displays (requires conference parameter)
ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q";
if (!(conf.canChangeConference()))
return new ErrorBox("Access Error","You are not permitted to change this conference's customizations.",
on_error);
try
{ // return the conference custom blocks view
return new ConferenceCustomBlocks(comm,conf);
} // end try
catch (DataException de)
{ // something wrong in the database
return new ErrorBox("Database Error","Database error getting custom blocks: " + de.getMessage(),
on_error);
} // end catch
} // end if ("U" command)
if (cmd.equals("UX"))
{ // "UX" = Customize Conference Displays (requires conference parameter)
ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=U";
if (!(conf.canChangeConference()))
return new ErrorBox("Access Error","You are not permitted to change this conference's customizations.",
on_error);
try
{ // zap the custom blocks
conf.removeCustomBlocks();
} // end try
catch (DataException de)
{ // something wrong in the database
return new ErrorBox("Database Error","Database error removing custom blocks: " + de.getMessage(),
on_error);
} // end catch
catch (AccessError ae)
{ // some lack of access is causing problems
return new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
// all done - bounce back to the menu
throw new RedirectResult("confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID()
+ "&cmd=Q");
} // end if ("UX" command)
if (cmd.equals("DEL")) if (cmd.equals("DEL"))
{ // "DEL" = "Delete Conference (requires conference parameter) { // "DEL" = "Delete Conference (requires conference parameter)
ConferenceContext conf = getConferenceParameter(request,comm,true,on_error); ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
@ -1139,6 +1197,51 @@ public class ConfOperations extends VeniceServlet
} // end if ("I" command) } // end if ("I" command)
if (cmd.equals("U"))
{ // "U" command - Customize Conference
ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=U";
if (!(conf.canChangeConference()))
return new ErrorBox("Access Error","You are not permitted to change this conference's customizations.",
on_error);
if (isImageButtonClicked(request,"cancel")) // cancel - bounce back to the menu
throw new RedirectResult("confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID()
+ "&cmd=Q");
if (isImageButtonClicked(request,"update"))
{ // OK, actually update the operation
try
{ // reset the custom blocks
conf.setCustomBlock(ConferenceContext.CUST_BLOCK_TOP,request.getParameter("tx"));
conf.setCustomBlock(ConferenceContext.CUST_BLOCK_BOTTOM,request.getParameter("bx"));
} // end try
catch (DataException de)
{ // something wrong in the database
return new ErrorBox("Database Error","Database error setting custom blocks: " + de.getMessage(),
on_error);
} // end catch
catch (AccessError ae)
{ // some lack of access is causing problems
return new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
// all done - bounce back to the menu
throw new RedirectResult("confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID()
+ "&cmd=Q");
} // end if
// we don't know what button was pressed
logger.error("no known button click on ConfOperations.doPost, cmd=U");
return new ErrorBox("Internal Error","Unknown command button pressed",on_error);
} // end if ("U" command)
// unrecognized command! // unrecognized command!
logger.error("invalid command to ConfOperations.doPost: " + cmd); logger.error("invalid command to ConfOperations.doPost: " + cmd);
return new ErrorBox("Internal Error","Invalid command to ConfOperations.doPost",on_error); return new ErrorBox("Internal Error","Invalid command to ConfOperations.doPost",on_error);

View File

@ -0,0 +1,150 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* 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.servlets.format;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
public class ConferenceCustomBlocks implements JSPRender
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
// Attribute name for request attribute
protected static final String ATTR_NAME = "com.silverwrist.venice.content.ConferenceCustomBlocks";
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private CommunityContext comm; // the community we're in
private ConferenceContext conf; // the conference being diddled with
private String top_custom; // the top custom block
private String bottom_custom; // the bottom custom block
private String locator = null; // locator string
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public ConferenceCustomBlocks(CommunityContext comm, ConferenceContext conf) throws DataException
{
this.comm = comm;
this.conf = conf;
this.top_custom = conf.getCustomBlock(ConferenceContext.CUST_BLOCK_TOP);
this.bottom_custom = conf.getCustomBlock(ConferenceContext.CUST_BLOCK_BOTTOM);
} // end constructor
/*--------------------------------------------------------------------------------
* External static functions
*--------------------------------------------------------------------------------
*/
public static ConferenceCustomBlocks retrieve(ServletRequest request)
{
return (ConferenceCustomBlocks)(request.getAttribute(ATTR_NAME));
} // end retrieve
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceContent
*--------------------------------------------------------------------------------
*/
public String getPageTitle(RenderData rdat)
{
return "Customize Conference: " + conf.getName();
} // end getPageTitle
public String getPageQID()
{
return null;
} // end getPageQID
/*--------------------------------------------------------------------------------
* Implementations from interface JSPRender
*--------------------------------------------------------------------------------
*/
public void store(ServletRequest request)
{
request.setAttribute(ATTR_NAME,this);
} // end store
public String getTargetJSPName()
{
return "conf_custom.jsp";
} // end getTargetJSPName
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public final int getCommunityID()
{
return comm.getCommunityID();
} // end getCommunityID
public final int getConferenceID()
{
return conf.getConfID();
} // end getConferenceID
public final String getConferenceName()
{
return conf.getName();
} // end getConferenceName
public final String getLocator()
{
if (locator==null)
locator = "sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID();
return locator;
} // end getLocator
public final String getTopCustomBlock()
{
return (top_custom==null) ? "" : StringUtil.encodeHTML(top_custom);
} // end getTopCustomBlock
public final String getBottomCustomBlock()
{
return (bottom_custom==null) ? "" : StringUtil.encodeHTML(bottom_custom);
} // end getBottomCustomBlock
} // end class ConferenceCustomBlocks

View File

@ -17,6 +17,8 @@
*/ */
package com.silverwrist.venice.servlets.format; package com.silverwrist.venice.servlets.format;
import java.io.IOException;
import java.io.Writer;
import java.util.*; import java.util.*;
import javax.servlet.*; import javax.servlet.*;
import javax.servlet.http.*; import javax.servlet.http.*;
@ -45,6 +47,8 @@ public class TopicListing implements JSPRender
private List topic_list; // the topic list private List topic_list; // the topic list
private TopicVisitOrder visit_order; // indicates order in which topics are visited private TopicVisitOrder visit_order; // indicates order in which topics are visited
private String qid; // "quick ID" for this page private String qid; // "quick ID" for this page
private String top_custom; // top custom HTML block
private String bottom_custom; // bottom custom HTML block
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructor * Constructor
@ -62,6 +66,8 @@ public class TopicListing implements JSPRender
this.visit_order = TopicVisitOrder.initialize(request.getSession(true),conf.getConfID(),this.topic_list); this.visit_order = TopicVisitOrder.initialize(request.getSession(true),conf.getConfID(),this.topic_list);
List aliases = conf.getAliases(); List aliases = conf.getAliases();
this.qid = "go/" + comm.getAlias() + "!" + (String)(aliases.get(0)); this.qid = "go/" + comm.getAlias() + "!" + (String)(aliases.get(0));
this.top_custom = conf.getCustomBlock(ConferenceContext.CUST_BLOCK_TOP);
this.bottom_custom = conf.getCustomBlock(ConferenceContext.CUST_BLOCK_BOTTOM);
} // end constructor } // end constructor
@ -115,19 +121,19 @@ public class TopicListing implements JSPRender
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
public int getCommunityID() public final int getCommunityID()
{ {
return comm.getCommunityID(); return comm.getCommunityID();
} // end getCommunityID } // end getCommunityID
public int getConfID() public final int getConfID()
{ {
return conf.getConfID(); return conf.getConfID();
} // end getConfID } // end getConfID
public String getLocator() public final String getLocator()
{ {
StringBuffer buf = new StringBuffer("sig="); StringBuffer buf = new StringBuffer("sig=");
buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID()); buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID());
@ -135,19 +141,19 @@ public class TopicListing implements JSPRender
} // end getLocator } // end getLocator
public String getConfName() public final String getConfName()
{ {
return conf.getName(); return conf.getName();
} // end getConfName } // end getConfName
public boolean canDoReadNew() public final boolean canDoReadNew()
{ {
return visit_order.isNext(); return visit_order.isNext();
} // end canDoReadNew } // end canDoReadNew
public String getNextLocator() public final String getNextLocator()
{ {
StringBuffer buf = new StringBuffer("sig="); StringBuffer buf = new StringBuffer("sig=");
buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID()).append("&top="); buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID()).append("&top=");
@ -156,46 +162,60 @@ public class TopicListing implements JSPRender
} // end getNextLocator } // end getNextLocator
public boolean canCreateTopic() public final boolean canCreateTopic()
{ {
return conf.canCreateTopic(); return conf.canCreateTopic();
} // end canCreateTopic } // end canCreateTopic
public boolean canAddToHotlist() public final boolean canAddToHotlist()
{ {
return conf.canAddToHotlist(); return conf.canAddToHotlist();
} // end canAddToHotlist } // end canAddToHotlist
public boolean anyTopics() public final boolean anyTopics()
{ {
return (topic_list.size()>0); return (topic_list.size()>0);
} // end anyTopics } // end anyTopics
public int getViewOption() public final int getViewOption()
{ {
return view_opt; return view_opt;
} // end getViewOption } // end getViewOption
public boolean isView(int value) public final boolean isView(int value)
{ {
return (view_opt==value); return (view_opt==value);
} // end isSort } // end isSort
public boolean isSort(int value) public final boolean isSort(int value)
{ {
return (sort_opt==value); return (sort_opt==value);
} // end isSort } // end isSort
public Iterator getTopicIterator() public final Iterator getTopicIterator()
{ {
return topic_list.iterator(); return topic_list.iterator();
} // end getTopicIterator } // end getTopicIterator
public final void writeTopCustom(Writer out) throws IOException
{
if (top_custom!=null)
out.write(top_custom);
} // end writeTopCustom
public final void writeBottomCustom(Writer out) throws IOException
{
if (bottom_custom!=null)
out.write(bottom_custom);
} // end writeBottomCustom
} // end class TopicListing } // end class TopicListing

View File

@ -18,6 +18,8 @@
package com.silverwrist.venice.servlets.format; package com.silverwrist.venice.servlets.format;
import java.awt.Dimension; import java.awt.Dimension;
import java.io.Writer;
import java.io.IOException;
import java.util.*; import java.util.*;
import javax.servlet.*; import javax.servlet.*;
import javax.servlet.http.*; import javax.servlet.http.*;
@ -59,6 +61,8 @@ public class TopicPosts implements JSPRender
private TopicVisitOrder visit_order; private TopicVisitOrder visit_order;
private String topic_stem; private String topic_stem;
private String topic_qid; private String topic_qid;
private String top_custom;
private String bottom_custom;
private String cache_locator = null; private String cache_locator = null;
private HashSet bozo_uids = new HashSet(); private HashSet bozo_uids = new HashSet();
private Dimension photo_size = null; private Dimension photo_size = null;
@ -97,6 +101,8 @@ public class TopicPosts implements JSPRender
List aliases = conf.getAliases(); List aliases = conf.getAliases();
topic_stem = (String)(aliases.get(0)) + "." + topic.getTopicNumber() + "."; topic_stem = (String)(aliases.get(0)) + "." + topic.getTopicNumber() + ".";
topic_qid = "go/" + comm.getAlias() + "!" + (String)(aliases.get(0)) + "." + topic.getTopicNumber(); topic_qid = "go/" + comm.getAlias() + "!" + (String)(aliases.get(0)) + "." + topic.getTopicNumber();
top_custom = conf.getCustomBlock(ConferenceContext.CUST_BLOCK_TOP);
bottom_custom = conf.getCustomBlock(ConferenceContext.CUST_BLOCK_BOTTOM);
// build up the list of users IN THIS VIEW that are bozo-filtered // build up the list of users IN THIS VIEW that are bozo-filtered
HashSet saw_users = new HashSet(); HashSet saw_users = new HashSet();
@ -192,7 +198,7 @@ public class TopicPosts implements JSPRender
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
public static String getPosterName(TopicMessageContext msg) public static final String getPosterName(TopicMessageContext msg)
{ {
try try
{ // have to guard agains a DataException here { // have to guard agains a DataException here
@ -207,7 +213,7 @@ public class TopicPosts implements JSPRender
} // end getPosterName } // end getPosterName
public static String getMessageBodyText(TopicMessageContext msg) public static final String getMessageBodyText(TopicMessageContext msg)
{ {
try try
{ // have to guard against a DataException here { // have to guard against a DataException here
@ -222,25 +228,25 @@ public class TopicPosts implements JSPRender
} // end getMessageBodyText } // end getMessageBodyText
public int getCommunityID() public final int getCommunityID()
{ {
return comm.getCommunityID(); return comm.getCommunityID();
} // end getCommunityID } // end getCommunityID
public int getConfID() public final int getConfID()
{ {
return conf.getConfID(); return conf.getConfID();
} // end getConfID } // end getConfID
public int getTopicNumber() public final int getTopicNumber()
{ {
return topic.getTopicNumber(); return topic.getTopicNumber();
} // end getTopicNumber } // end getTopicNumber
public int getNextTopicNumber() public final int getNextTopicNumber()
{ {
if (visit_order!=null) if (visit_order!=null)
return visit_order.getNext(); return visit_order.getNext();
@ -249,7 +255,7 @@ public class TopicPosts implements JSPRender
} // end getNextTopicNumber } // end getNextTopicNumber
public String getConfLocator() public final String getConfLocator()
{ {
StringBuffer buf = new StringBuffer("sig="); StringBuffer buf = new StringBuffer("sig=");
buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID()); buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID());
@ -257,7 +263,7 @@ public class TopicPosts implements JSPRender
} // end getConfLocator } // end getConfLocator
public String getLocator() public final String getLocator()
{ {
if (cache_locator==null) if (cache_locator==null)
{ // build up the standard locator { // build up the standard locator
@ -272,7 +278,7 @@ public class TopicPosts implements JSPRender
} // end getLocator } // end getLocator
public String getNextLocator() public final String getNextLocator()
{ {
StringBuffer buf = new StringBuffer("sig="); StringBuffer buf = new StringBuffer("sig=");
buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID()); buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID());
@ -282,7 +288,7 @@ public class TopicPosts implements JSPRender
} // end getNextLocator } // end getNextLocator
public String getRestoreLocator() public final String getRestoreLocator()
{ {
StringBuffer buf = new StringBuffer("rtop="); StringBuffer buf = new StringBuffer("rtop=");
buf.append(topic.getTopicNumber()).append("&rct=").append(unread); buf.append(topic.getTopicNumber()).append("&rct=").append(unread);
@ -290,7 +296,7 @@ public class TopicPosts implements JSPRender
} // end getRestoreLocator } // end getRestoreLocator
public String getIdentifyingData() public final String getIdentifyingData()
{ {
StringBuffer buf = new StringBuffer("Posts "); StringBuffer buf = new StringBuffer("Posts ");
buf.append(first).append(" through ").append(last).append(" in topic #").append(topic.getTopicID()); buf.append(first).append(" through ").append(last).append(" in topic #").append(topic.getTopicID());
@ -298,37 +304,37 @@ public class TopicPosts implements JSPRender
} // end getIdentifyingData } // end getIdentifyingData
public String getTopicName() public final String getTopicName()
{ {
return topic.getName(); return topic.getName();
} // end getTopicName } // end getTopicName
public int getTotalMessages() public final int getTotalMessages()
{ {
return topic.getTotalMessages(); return topic.getTotalMessages();
} // end getTotalMessages } // end getTotalMessages
public int getNewMessages() public final int getNewMessages()
{ {
return unread; return unread;
} // end getNewMessages } // end getNewMessages
public Date getLastUpdate() public final Date getLastUpdate()
{ {
return topic.getLastUpdateDate(); return topic.getLastUpdateDate();
} // end getLastUpdate } // end getLastUpdate
public boolean isTopicHidden() public final boolean isTopicHidden()
{ {
return topic.isHidden(); return topic.isHidden();
} // end isTopicHidden } // end isTopicHidden
public boolean canDoNextTopic() public final boolean canDoNextTopic()
{ {
if (visit_order!=null) if (visit_order!=null)
return visit_order.isNext(); return visit_order.isNext();
@ -337,43 +343,43 @@ public class TopicPosts implements JSPRender
} // end canDoNextTopic } // end canDoNextTopic
public boolean canFreezeTopic() public final boolean canFreezeTopic()
{ {
return topic.canFreeze(); return topic.canFreeze();
} // end canFreezeTopic } // end canFreezeTopic
public boolean isTopicFrozen() public final boolean isTopicFrozen()
{ {
return topic.isFrozen(); return topic.isFrozen();
} // end isTopicFrozen } // end isTopicFrozen
public boolean canArchiveTopic() public final boolean canArchiveTopic()
{ {
return topic.canArchive(); return topic.canArchive();
} // end canArchiveTopic } // end canArchiveTopic
public boolean isTopicArchived() public final boolean isTopicArchived()
{ {
return topic.isArchived(); return topic.isArchived();
} // end isTopicArchived } // end isTopicArchived
public boolean canDeleteTopic() public final boolean canDeleteTopic()
{ {
return topic.canDelete(); return topic.canDelete();
} // end canDeleteTopic } // end canDeleteTopic
public boolean canScrollUp() public final boolean canScrollUp()
{ {
return (first>0); return (first>0);
} // end canScrollUp } // end canScrollUp
public String getScrollUpLocator() public final String getScrollUpLocator()
{ {
int new_first = first - engine.getNumPostsPerPage(); int new_first = first - engine.getNumPostsPerPage();
int new_last = first - 1; int new_last = first - 1;
@ -390,13 +396,13 @@ public class TopicPosts implements JSPRender
} // end getScrollUpLocator } // end getScrollUpLocator
public boolean canScrollDown() public final boolean canScrollDown()
{ {
return ((topic.getTotalMessages() - (1 + last))>0); return ((topic.getTotalMessages() - (1 + last))>0);
} // end canScrollDown } // end canScrollDown
public String getScrollDownLocator() public final String getScrollDownLocator()
{ {
int new_last = last + engine.getNumPostsPerPage(); int new_last = last + engine.getNumPostsPerPage();
int my_last = topic.getTotalMessages() - 1; int my_last = topic.getTotalMessages() - 1;
@ -408,13 +414,13 @@ public class TopicPosts implements JSPRender
} // end getScrollDownLocator } // end getScrollDownLocator
public boolean canScrollToEnd() public final boolean canScrollToEnd()
{ {
return ((topic.getTotalMessages() - (1 + last))>0); return ((topic.getTotalMessages() - (1 + last))>0);
} // end canScrollToEnd } // end canScrollToEnd
public String getScrollToEndLocator() public final String getScrollToEndLocator()
{ {
int my_last = topic.getTotalMessages(); int my_last = topic.getTotalMessages();
StringBuffer buf = new StringBuffer("p1="); StringBuffer buf = new StringBuffer("p1=");
@ -423,25 +429,25 @@ public class TopicPosts implements JSPRender
} // end getScrollToEndLocator } // end getScrollToEndLocator
public Iterator getMessageIterator() public final Iterator getMessageIterator()
{ {
return messages.iterator(); return messages.iterator();
} // end getMessageIterator() } // end getMessageIterator()
public boolean emitBreakLinePoint(int msg) public final boolean emitBreakLinePoint(int msg)
{ {
return (msg==(topic.getTotalMessages()-unread)); return (msg==(topic.getTotalMessages()-unread));
} // end emitBreakLinePoint } // end emitBreakLinePoint
public boolean showAdvanced() public final boolean showAdvanced()
{ {
return show_advanced && (last==first); return show_advanced && (last==first);
} // end showAdvanced } // end showAdvanced
public boolean displayPostBox() public final boolean displayPostBox()
{ {
boolean flag1 = conf.canPostToConference(); boolean flag1 = conf.canPostToConference();
boolean flag2 = (topic.isFrozen() ? topic.canFreeze() : true); boolean flag2 = (topic.isFrozen() ? topic.canFreeze() : true);
@ -450,25 +456,25 @@ public class TopicPosts implements JSPRender
} // end displayPostBox } // end displayPostBox
public String getDefaultPseud() public final String getDefaultPseud()
{ {
return conf.getDefaultPseud(); return conf.getDefaultPseud();
} // end getDefaultPseud } // end getDefaultPseud
public String getMessageReference(TopicMessageContext msg) public final String getMessageReference(TopicMessageContext msg)
{ {
return topic_stem + msg.getPostNumber(); return topic_stem + msg.getPostNumber();
} // end getMessageReference } // end getMessageReference
public int getNumPostsPerPage() public final int getNumPostsPerPage()
{ {
return engine.getNumPostsPerPage(); return engine.getNumPostsPerPage();
} // end getNumPostsPerPage } // end getNumPostsPerPage
public boolean displayAttachmentInNewWindow(TopicMessageContext msg) public final boolean displayAttachmentInNewWindow(TopicMessageContext msg)
{ {
if (!(msg.hasAttachment())) if (!(msg.hasAttachment()))
return false; return false;
@ -477,7 +483,7 @@ public class TopicPosts implements JSPRender
} // end displayAttachmentInNewWindow } // end displayAttachmentInNewWindow
public boolean bozoFilterUser(int uid) public final boolean bozoFilterUser(int uid)
{ {
if (no_bozos) if (no_bozos)
return false; return false;
@ -486,7 +492,7 @@ public class TopicPosts implements JSPRender
} // end bozoFilterUser } // end bozoFilterUser
public boolean showBozoFilteredIndicator(int uid) public final boolean showBozoFilteredIndicator(int uid)
{ {
if (no_bozos) if (no_bozos)
return bozo_uids.contains(new Integer(uid)); return bozo_uids.contains(new Integer(uid));
@ -495,13 +501,13 @@ public class TopicPosts implements JSPRender
} // end showBozoFilteredIndicator } // end showBozoFilteredIndicator
public boolean showFilterButton(int uid) public final boolean showFilterButton(int uid)
{ {
return !(bozo_uids.contains(new Integer(uid))) && topic.canSetBozo(uid); return !(bozo_uids.contains(new Integer(uid))) && topic.canSetBozo(uid);
} // end showFilterButton } // end showFilterButton
public String getUserPhotoTag(int uid, RenderData rdat) public final String getUserPhotoTag(int uid, RenderData rdat)
{ {
if (photo_size==null) if (photo_size==null)
return ""; // user photos not enabled return ""; // user photos not enabled
@ -515,10 +521,24 @@ public class TopicPosts implements JSPRender
} // end getUserPhotoTag } // end getUserPhotoTag
public boolean displayPostPictures() public final boolean displayPostPictures()
{ {
return (photo_size!=null); return (photo_size!=null);
} // end displayPostPictures } // end displayPostPictures
public final void writeTopCustom(Writer out) throws IOException
{
if (top_custom!=null)
out.write(top_custom);
} // end writeTopCustom
public final void writeBottomCustom(Writer out) throws IOException
{
if (bottom_custom!=null)
out.write(bottom_custom);
} // end writeBottomCustom
} // end class TopicPosts } // end class TopicPosts

View File

@ -0,0 +1,69 @@
<%--
The contents of this file are subject to the Mozilla Public License Version 1.1
(the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
WARRANTY OF ANY KIND, either express or implied. See the License for the specific
language governing rights and limitations under the License.
The Original Code is the Venice Web Communities System.
The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
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):
--%>
<%@ page import = "java.util.*" %>
<%@ page import = "com.silverwrist.util.StringUtil" %>
<%@ page import = "com.silverwrist.venice.core.*" %>
<%@ page import = "com.silverwrist.venice.servlets.Variables" %>
<%@ page import = "com.silverwrist.venice.servlets.format.*" %>
<%
ConferenceCustomBlocks data = ConferenceCustomBlocks.retrieve(request);
Variables.failIfNull(data);
RenderData rdat = RenderConfig.createRenderData(application,request,response);
%>
<% if (rdat.useHTMLComments()) { %><!-- Custom blocks for conference #<%= data.getConferenceID() %> --><% } %>
<% rdat.writeContentHeader(out,"Customize Conference:",data.getConferenceName()); %>
<FORM METHOD="POST" ACTION="<%= rdat.getEncodedServletPath("confops") %>"><DIV CLASS="content">
<INPUT TYPE="HIDDEN" NAME="sig" VALUE="<%= data.getCommunityID() %>">
<INPUT TYPE="HIDDEN" NAME="conf" VALUE="<%= data.getConferenceID() %>">
<INPUT TYPE="HIDDEN" NAME="cmd" VALUE="U">
<TABLE BORDER=0 CELLPADDING=0>
<TR VALIGN=MIDDLE>
<TD ALIGN=LEFT CLASS="content" COLSPAN=2><%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
Custom HTML block to appear at top of Topic List/Posts pages:
</FONT></TD>
</TR>
<TR VALIGN=MIDDLE>
<TD ALIGN=LEFT CLASS="cinput" COLSPAN=2>
<TEXTAREA NAME="tx" WRAP=HARD ROWS=7 COLS=80><%= data.getTopCustomBlock() %></TEXTAREA>
</TD>
</TR>
<TR VALIGN=MIDDLE>
<TD ALIGN=LEFT CLASS="content" COLSPAN=2><%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
Custom HTML block to appear at bottom of Topic List/Posts pages:
</FONT></TD>
</TR>
<TR VALIGN=MIDDLE>
<TD ALIGN=LEFT CLASS="cinput" COLSPAN=2>
<TEXTAREA NAME="bx" WRAP=HARD ROWS=7 COLS=80><%= data.getBottomCustomBlock() %></TEXTAREA>
</TD>
</TR>
<TR VALIGN=MIDDLE>
<TD ALIGN=LEFT CLASS="content">
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_update.gif") %>" NAME="update"
ALT="Update" WIDTH=80 HEIGHT=24 BORDER=0>&nbsp;
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_cancel.gif") %>" NAME="cancel"
ALT="Cancel" WIDTH=80 HEIGHT=24 BORDER=0>
</TD>
<TD ALIGN=RIGHT CLASS="content">
<A HREF="<%= rdat.getEncodedServletPath("confops?cmd=UX&" + data.getLocator()) %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_remove.gif") %>" ALT="Remove" WIDTH=80 HEIGHT=24 BORDER=0></A>
</TD>
</TR>
</TABLE>
</DIV></FORM>

View File

@ -73,6 +73,8 @@
Conference Aliases</A><P> Conference Aliases</A><P>
<A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=M") %>">Manage <A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=M") %>">Manage
Conference Members</A><P> Conference Members</A><P>
<A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=U") %>">Customize
Conference Appearance</A><P>
<A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=QR") %>">Conference <A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=QR") %>">Conference
Activity Reports</A><P> Activity Reports</A><P>
<A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=I") %>">Conference <A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=I") %>">Conference

View File

@ -37,6 +37,7 @@
</B></FONT></SPAN> </B></FONT></SPAN>
<HR ALIGN=LEFT SIZE=2 WIDTH="90%" NOSHADE> <HR ALIGN=LEFT SIZE=2 WIDTH="90%" NOSHADE>
<% data.writeTopCustom(out); %>
<TABLE BORDER=0 WIDTH="100%" CELLPADDING=0 CELLSPACING=0> <TABLE BORDER=0 WIDTH="100%" CELLPADDING=0 CELLSPACING=0>
<TR VALIGN=BOTTOM> <TR VALIGN=BOTTOM>
<TD NOWRAP ALIGN=LEFT COLSPAN=2 CLASS="content"> <TD NOWRAP ALIGN=LEFT COLSPAN=2 CLASS="content">
@ -383,3 +384,4 @@
<DIV ALIGN=CENTER CLASS="content"><%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %><B>This is a <DIV ALIGN=CENTER CLASS="content"><%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %><B>This is a
<EM>Frozen</EM> Topic</B></DIV> <EM>Frozen</EM> Topic</B></DIV>
<% } // end if %> <% } // end if %>
<% data.writeBottomCustom(out); %>

View File

@ -30,6 +30,8 @@
%> %>
<% if (rdat.useHTMLComments()) { %><!-- Topic list for conf #<%= data.getConfID() %> --><% } %> <% if (rdat.useHTMLComments()) { %><!-- Topic list for conf #<%= data.getConfID() %> --><% } %>
<% rdat.writeContentHeader(out,"Topics in " + data.getConfName(),null); %> <% rdat.writeContentHeader(out,"Topics in " + data.getConfName(),null); %>
<% data.writeTopCustom(out); %>
<%= stdfont %> <%= stdfont %>
<DIV ALIGN="LEFT" CLASS="content"> <DIV ALIGN="LEFT" CLASS="content">
<A HREF="<%= rdat.getEncodedServletPath("confops?sig=" + data.getCommunityID()) %>"><IMG <A HREF="<%= rdat.getEncodedServletPath("confops?sig=" + data.getCommunityID()) %>"><IMG
@ -191,3 +193,4 @@
<B>]</B> <B>]</B>
</DIV> </DIV>
</FONT> </FONT>
<% data.writeBottomCustom(out); %>