diff --git a/setup/database.sql b/setup/database.sql index 8cda1e6..fac448f 100644 --- a/setup/database.sql +++ b/setup/database.sql @@ -310,6 +310,14 @@ CREATE TABLE propconf ( 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. CREATE TABLE topics ( topicid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, diff --git a/src/com/silverwrist/venice/core/ConferenceContext.java b/src/com/silverwrist/venice/core/ConferenceContext.java index e296afd..e0d19a7 100644 --- a/src/com/silverwrist/venice/core/ConferenceContext.java +++ b/src/com/silverwrist/venice/core/ConferenceContext.java @@ -40,6 +40,9 @@ public interface ConferenceContext public static final int SORT_TOTAL = 4; 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 String getName(); @@ -174,4 +177,10 @@ public interface ConferenceContext public abstract void sendMailToParticipants(boolean posters, int day_limit, String subject, String text) 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 diff --git a/src/com/silverwrist/venice/core/impl/BackgroundCommunityPurge.java b/src/com/silverwrist/venice/core/impl/BackgroundCommunityPurge.java index 5a6c6de..134f109 100644 --- a/src/com/silverwrist/venice/core/impl/BackgroundCommunityPurge.java +++ b/src/com/silverwrist/venice/core/impl/BackgroundCommunityPurge.java @@ -129,6 +129,7 @@ class BackgroundCommunityPurge implements Runnable stmt.executeUpdate("DELETE FROM confs WHERE confid = " + key + ";"); stmt.executeUpdate("DELETE FROM confalias 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 // that information to queue up the conference deletion diff --git a/src/com/silverwrist/venice/core/impl/BackgroundConferencePurge.java b/src/com/silverwrist/venice/core/impl/BackgroundConferencePurge.java index 73944d6..8db9dce 100644 --- a/src/com/silverwrist/venice/core/impl/BackgroundConferencePurge.java +++ b/src/com/silverwrist/venice/core/impl/BackgroundConferencePurge.java @@ -80,6 +80,7 @@ class BackgroundConferencePurge implements Runnable stmt.executeUpdate("DELETE FROM confsettings WHERE confid = " + confid + ";"); stmt.executeUpdate("DELETE FROM confhotlist 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 int[] topicids = new int[num_topics]; diff --git a/src/com/silverwrist/venice/core/impl/ConferenceCommunityContextImpl.java b/src/com/silverwrist/venice/core/impl/ConferenceCommunityContextImpl.java index 024112d..0c63c0f 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceCommunityContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceCommunityContextImpl.java @@ -772,4 +772,22 @@ class ConferenceCommunityContextImpl implements ConferenceCommunityContext } // 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 diff --git a/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java b/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java index a5c06c1..f33a538 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java @@ -17,6 +17,7 @@ */ package com.silverwrist.venice.core.impl; +import java.lang.ref.*; import java.sql.*; import java.util.*; import org.apache.log4j.*; @@ -67,6 +68,9 @@ class ConferenceCoreData implements ConferenceData private boolean creating_topic = false; // is somebody creating a topic? private boolean deleted = false; // has this conference been deleted? 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 @@ -97,6 +101,7 @@ class ConferenceCoreData implements ConferenceData loadData(rs); // load the conference data flags = new OptionSet(); loadProperties(conn); + loadCustom(conn); } // end try catch (SQLException e) @@ -185,6 +190,36 @@ class ConferenceCoreData implements ConferenceData } // 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 { Statement stmt = conn.createStatement(); @@ -1269,6 +1304,160 @@ class ConferenceCoreData implements ConferenceData } // 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) *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java b/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java index d25a082..ae28e97 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java @@ -1591,6 +1591,40 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend } // 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 *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/internals/ConferenceCommunityContext.java b/src/com/silverwrist/venice/core/internals/ConferenceCommunityContext.java index 80d473b..d5c4f0a 100644 --- a/src/com/silverwrist/venice/core/internals/ConferenceCommunityContext.java +++ b/src/com/silverwrist/venice/core/internals/ConferenceCommunityContext.java @@ -115,4 +115,10 @@ public interface ConferenceCommunityContext 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 diff --git a/src/com/silverwrist/venice/core/internals/ConferenceData.java b/src/com/silverwrist/venice/core/internals/ConferenceData.java index d266a24..3447220 100644 --- a/src/com/silverwrist/venice/core/internals/ConferenceData.java +++ b/src/com/silverwrist/venice/core/internals/ConferenceData.java @@ -109,4 +109,10 @@ public interface ConferenceData 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 diff --git a/src/com/silverwrist/venice/servlets/ConfOperations.java b/src/com/silverwrist/venice/servlets/ConfOperations.java index 845ac7d..4112d00 100644 --- a/src/com/silverwrist/venice/servlets/ConfOperations.java +++ b/src/com/silverwrist/venice/servlets/ConfOperations.java @@ -168,6 +168,8 @@ public class ConfOperations extends VeniceServlet * SH = Hide/show conference from sequence manager menu * SS = Change conference sequence from sequence manager menu * 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 */ @@ -337,8 +339,8 @@ public class ConfOperations extends VeniceServlet String message = "You are about to permanently delete the \"" + conf.getName() + "\" conference! " + "Are you sure you want to do this?"; return new ConfirmBox(request,DELETE_CONFIRM_ATTR,DELETE_CONFIRM_PARAM,"Delete Conference",message, - "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=SDEL", - on_error); + "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + + "&cmd=SDEL",on_error); } // end else @@ -495,7 +497,8 @@ public class ConfOperations extends VeniceServlet try { // 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); } // end try @@ -602,7 +605,7 @@ public class ConfOperations extends VeniceServlet } // end try catch (DataException de) { // 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); } // end catch @@ -614,6 +617,61 @@ public class ConfOperations extends VeniceServlet } // 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")) { // "DEL" = "Delete Conference (requires conference parameter) ConferenceContext conf = getConferenceParameter(request,comm,true,on_error); @@ -1139,6 +1197,51 @@ public class ConfOperations extends VeniceServlet } // 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! logger.error("invalid command to ConfOperations.doPost: " + cmd); return new ErrorBox("Internal Error","Invalid command to ConfOperations.doPost",on_error); diff --git a/src/com/silverwrist/venice/servlets/format/ConferenceCustomBlocks.java b/src/com/silverwrist/venice/servlets/format/ConferenceCustomBlocks.java new file mode 100644 index 0000000..242e967 --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/ConferenceCustomBlocks.java @@ -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 . + * + * 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 , + * 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 diff --git a/src/com/silverwrist/venice/servlets/format/TopicListing.java b/src/com/silverwrist/venice/servlets/format/TopicListing.java index 2c43c4a..babcba6 100644 --- a/src/com/silverwrist/venice/servlets/format/TopicListing.java +++ b/src/com/silverwrist/venice/servlets/format/TopicListing.java @@ -17,6 +17,8 @@ */ package com.silverwrist.venice.servlets.format; +import java.io.IOException; +import java.io.Writer; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; @@ -45,6 +47,8 @@ public class TopicListing implements JSPRender private List topic_list; // the topic list private TopicVisitOrder visit_order; // indicates order in which topics are visited 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 @@ -62,6 +66,8 @@ public class TopicListing implements JSPRender this.visit_order = TopicVisitOrder.initialize(request.getSession(true),conf.getConfID(),this.topic_list); List aliases = conf.getAliases(); 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 @@ -115,19 +121,19 @@ public class TopicListing implements JSPRender *-------------------------------------------------------------------------------- */ - public int getCommunityID() + public final int getCommunityID() { return comm.getCommunityID(); } // end getCommunityID - public int getConfID() + public final int getConfID() { return conf.getConfID(); } // end getConfID - public String getLocator() + public final String getLocator() { StringBuffer buf = new StringBuffer("sig="); buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID()); @@ -135,19 +141,19 @@ public class TopicListing implements JSPRender } // end getLocator - public String getConfName() + public final String getConfName() { return conf.getName(); } // end getConfName - public boolean canDoReadNew() + public final boolean canDoReadNew() { return visit_order.isNext(); } // end canDoReadNew - public String getNextLocator() + public final String getNextLocator() { StringBuffer buf = new StringBuffer("sig="); buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID()).append("&top="); @@ -156,46 +162,60 @@ public class TopicListing implements JSPRender } // end getNextLocator - public boolean canCreateTopic() + public final boolean canCreateTopic() { return conf.canCreateTopic(); } // end canCreateTopic - public boolean canAddToHotlist() + public final boolean canAddToHotlist() { return conf.canAddToHotlist(); } // end canAddToHotlist - public boolean anyTopics() + public final boolean anyTopics() { return (topic_list.size()>0); } // end anyTopics - public int getViewOption() + public final int getViewOption() { return view_opt; } // end getViewOption - public boolean isView(int value) + public final boolean isView(int value) { return (view_opt==value); } // end isSort - public boolean isSort(int value) + public final boolean isSort(int value) { return (sort_opt==value); } // end isSort - public Iterator getTopicIterator() + public final Iterator getTopicIterator() { return topic_list.iterator(); } // 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 diff --git a/src/com/silverwrist/venice/servlets/format/TopicPosts.java b/src/com/silverwrist/venice/servlets/format/TopicPosts.java index 54591fe..e49bfef 100644 --- a/src/com/silverwrist/venice/servlets/format/TopicPosts.java +++ b/src/com/silverwrist/venice/servlets/format/TopicPosts.java @@ -18,6 +18,8 @@ package com.silverwrist.venice.servlets.format; import java.awt.Dimension; +import java.io.Writer; +import java.io.IOException; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; @@ -59,6 +61,8 @@ public class TopicPosts implements JSPRender private TopicVisitOrder visit_order; private String topic_stem; private String topic_qid; + private String top_custom; + private String bottom_custom; private String cache_locator = null; private HashSet bozo_uids = new HashSet(); private Dimension photo_size = null; @@ -97,6 +101,8 @@ public class TopicPosts implements JSPRender List aliases = conf.getAliases(); topic_stem = (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 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 { // have to guard agains a DataException here @@ -207,7 +213,7 @@ public class TopicPosts implements JSPRender } // end getPosterName - public static String getMessageBodyText(TopicMessageContext msg) + public static final String getMessageBodyText(TopicMessageContext msg) { try { // have to guard against a DataException here @@ -222,25 +228,25 @@ public class TopicPosts implements JSPRender } // end getMessageBodyText - public int getCommunityID() + public final int getCommunityID() { return comm.getCommunityID(); } // end getCommunityID - public int getConfID() + public final int getConfID() { return conf.getConfID(); } // end getConfID - public int getTopicNumber() + public final int getTopicNumber() { return topic.getTopicNumber(); } // end getTopicNumber - public int getNextTopicNumber() + public final int getNextTopicNumber() { if (visit_order!=null) return visit_order.getNext(); @@ -249,7 +255,7 @@ public class TopicPosts implements JSPRender } // end getNextTopicNumber - public String getConfLocator() + public final String getConfLocator() { StringBuffer buf = new StringBuffer("sig="); buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID()); @@ -257,7 +263,7 @@ public class TopicPosts implements JSPRender } // end getConfLocator - public String getLocator() + public final String getLocator() { if (cache_locator==null) { // build up the standard locator @@ -272,7 +278,7 @@ public class TopicPosts implements JSPRender } // end getLocator - public String getNextLocator() + public final String getNextLocator() { StringBuffer buf = new StringBuffer("sig="); buf.append(comm.getCommunityID()).append("&conf=").append(conf.getConfID()); @@ -282,7 +288,7 @@ public class TopicPosts implements JSPRender } // end getNextLocator - public String getRestoreLocator() + public final String getRestoreLocator() { StringBuffer buf = new StringBuffer("rtop="); buf.append(topic.getTopicNumber()).append("&rct=").append(unread); @@ -290,7 +296,7 @@ public class TopicPosts implements JSPRender } // end getRestoreLocator - public String getIdentifyingData() + public final String getIdentifyingData() { StringBuffer buf = new StringBuffer("Posts "); buf.append(first).append(" through ").append(last).append(" in topic #").append(topic.getTopicID()); @@ -298,37 +304,37 @@ public class TopicPosts implements JSPRender } // end getIdentifyingData - public String getTopicName() + public final String getTopicName() { return topic.getName(); } // end getTopicName - public int getTotalMessages() + public final int getTotalMessages() { return topic.getTotalMessages(); } // end getTotalMessages - public int getNewMessages() + public final int getNewMessages() { return unread; } // end getNewMessages - public Date getLastUpdate() + public final Date getLastUpdate() { return topic.getLastUpdateDate(); } // end getLastUpdate - public boolean isTopicHidden() + public final boolean isTopicHidden() { return topic.isHidden(); } // end isTopicHidden - public boolean canDoNextTopic() + public final boolean canDoNextTopic() { if (visit_order!=null) return visit_order.isNext(); @@ -337,43 +343,43 @@ public class TopicPosts implements JSPRender } // end canDoNextTopic - public boolean canFreezeTopic() + public final boolean canFreezeTopic() { return topic.canFreeze(); } // end canFreezeTopic - public boolean isTopicFrozen() + public final boolean isTopicFrozen() { return topic.isFrozen(); } // end isTopicFrozen - public boolean canArchiveTopic() + public final boolean canArchiveTopic() { return topic.canArchive(); } // end canArchiveTopic - public boolean isTopicArchived() + public final boolean isTopicArchived() { return topic.isArchived(); } // end isTopicArchived - public boolean canDeleteTopic() + public final boolean canDeleteTopic() { return topic.canDelete(); } // end canDeleteTopic - public boolean canScrollUp() + public final boolean canScrollUp() { return (first>0); } // end canScrollUp - public String getScrollUpLocator() + public final String getScrollUpLocator() { int new_first = first - engine.getNumPostsPerPage(); int new_last = first - 1; @@ -390,13 +396,13 @@ public class TopicPosts implements JSPRender } // end getScrollUpLocator - public boolean canScrollDown() + public final boolean canScrollDown() { return ((topic.getTotalMessages() - (1 + last))>0); } // end canScrollDown - public String getScrollDownLocator() + public final String getScrollDownLocator() { int new_last = last + engine.getNumPostsPerPage(); int my_last = topic.getTotalMessages() - 1; @@ -408,13 +414,13 @@ public class TopicPosts implements JSPRender } // end getScrollDownLocator - public boolean canScrollToEnd() + public final boolean canScrollToEnd() { return ((topic.getTotalMessages() - (1 + last))>0); } // end canScrollToEnd - public String getScrollToEndLocator() + public final String getScrollToEndLocator() { int my_last = topic.getTotalMessages(); StringBuffer buf = new StringBuffer("p1="); @@ -423,25 +429,25 @@ public class TopicPosts implements JSPRender } // end getScrollToEndLocator - public Iterator getMessageIterator() + public final Iterator getMessageIterator() { return messages.iterator(); } // end getMessageIterator() - public boolean emitBreakLinePoint(int msg) + public final boolean emitBreakLinePoint(int msg) { return (msg==(topic.getTotalMessages()-unread)); } // end emitBreakLinePoint - public boolean showAdvanced() + public final boolean showAdvanced() { return show_advanced && (last==first); } // end showAdvanced - public boolean displayPostBox() + public final boolean displayPostBox() { boolean flag1 = conf.canPostToConference(); boolean flag2 = (topic.isFrozen() ? topic.canFreeze() : true); @@ -450,25 +456,25 @@ public class TopicPosts implements JSPRender } // end displayPostBox - public String getDefaultPseud() + public final String getDefaultPseud() { return conf.getDefaultPseud(); } // end getDefaultPseud - public String getMessageReference(TopicMessageContext msg) + public final String getMessageReference(TopicMessageContext msg) { return topic_stem + msg.getPostNumber(); } // end getMessageReference - public int getNumPostsPerPage() + public final int getNumPostsPerPage() { return engine.getNumPostsPerPage(); } // end getNumPostsPerPage - public boolean displayAttachmentInNewWindow(TopicMessageContext msg) + public final boolean displayAttachmentInNewWindow(TopicMessageContext msg) { if (!(msg.hasAttachment())) return false; @@ -477,7 +483,7 @@ public class TopicPosts implements JSPRender } // end displayAttachmentInNewWindow - public boolean bozoFilterUser(int uid) + public final boolean bozoFilterUser(int uid) { if (no_bozos) return false; @@ -486,7 +492,7 @@ public class TopicPosts implements JSPRender } // end bozoFilterUser - public boolean showBozoFilteredIndicator(int uid) + public final boolean showBozoFilteredIndicator(int uid) { if (no_bozos) return bozo_uids.contains(new Integer(uid)); @@ -495,13 +501,13 @@ public class TopicPosts implements JSPRender } // end showBozoFilteredIndicator - public boolean showFilterButton(int uid) + public final boolean showFilterButton(int uid) { return !(bozo_uids.contains(new Integer(uid))) && topic.canSetBozo(uid); } // end showFilterButton - public String getUserPhotoTag(int uid, RenderData rdat) + public final String getUserPhotoTag(int uid, RenderData rdat) { if (photo_size==null) return ""; // user photos not enabled @@ -515,10 +521,24 @@ public class TopicPosts implements JSPRender } // end getUserPhotoTag - public boolean displayPostPictures() + public final boolean displayPostPictures() { return (photo_size!=null); } // 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 diff --git a/web/format/conf_custom.jsp b/web/format/conf_custom.jsp new file mode 100644 index 0000000..ca481f9 --- /dev/null +++ b/web/format/conf_custom.jsp @@ -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 . + + 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 , + 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()) { %><% } %> +<% rdat.writeContentHeader(out,"Customize Conference:",data.getConferenceName()); %> + +
">
+ + + + + + + + + + + + + + + + + + + + +
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %> + Custom HTML block to appear at top of Topic List/Posts pages: +
+ +
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %> + Custom HTML block to appear at bottom of Topic List/Posts pages: +
+ +
+ " NAME="update" + ALT="Update" WIDTH=80 HEIGHT=24 BORDER=0>  + " NAME="cancel" + ALT="Cancel" WIDTH=80 HEIGHT=24 BORDER=0> + + ">" ALT="Remove" WIDTH=80 HEIGHT=24 BORDER=0> +
+
\ No newline at end of file diff --git a/web/format/manage_conf.jsp b/web/format/manage_conf.jsp index a88609d..7bdf130 100644 --- a/web/format/manage_conf.jsp +++ b/web/format/manage_conf.jsp @@ -73,6 +73,8 @@ Conference Aliases

">Manage Conference Members

+ ">Customize + Conference Appearance

">Conference Activity Reports

">Conference diff --git a/web/format/posts.jsp b/web/format/posts.jsp index b76719b..483b89f 100644 --- a/web/format/posts.jsp +++ b/web/format/posts.jsp @@ -37,6 +37,7 @@


+<% data.writeTopCustom(out); %>
@@ -383,3 +384,4 @@
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>This is a Frozen Topic
<% } // end if %> +<% data.writeBottomCustom(out); %> diff --git a/web/format/topics.jsp b/web/format/topics.jsp index fe12f41..a79ffb4 100644 --- a/web/format/topics.jsp +++ b/web/format/topics.jsp @@ -30,6 +30,8 @@ %> <% if (rdat.useHTMLComments()) { %><% } %> <% rdat.writeContentHeader(out,"Topics in " + data.getConfName(),null); %> + +<% data.writeTopCustom(out); %> <%= stdfont %> +<% data.writeBottomCustom(out); %>