implemented front page content management, finally wired up the user locale
and timezone default mechanism, and did some other bugfixing and stuff
This commit is contained in:
		
							parent
							
								
									129b69973b
								
							
						
					
					
						commit
						2e455b4bdd
					
				
							
								
								
									
										5
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								TODO
									
									
									
									
									
								
							@ -17,11 +17,6 @@ Lots!
 | 
			
		||||
- Unimplemented functions on the Top page:
 | 
			
		||||
  Customize Sideboxes
 | 
			
		||||
 | 
			
		||||
- The plan for the "main" part of the Top page is to let a sysadmin put
 | 
			
		||||
  notices there by "publishing" selected conference messages to the front page.
 | 
			
		||||
  We may include a welcome message up top to be displayed if the user's not
 | 
			
		||||
  logged in.
 | 
			
		||||
 | 
			
		||||
- Slippage during posting is still untested.
 | 
			
		||||
 | 
			
		||||
- Not everybody likes purple.  Provide a way to change the default colors.
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
advogato
 | 
			
		||||
ain't
 | 
			
		||||
anime
 | 
			
		||||
anla'shok
 | 
			
		||||
bajor
 | 
			
		||||
bios
 | 
			
		||||
 | 
			
		||||
@ -50,4 +50,20 @@
 | 
			
		||||
    <site-logo>http://delenn:8080/venice/images/powered-by-venice.gif</site-logo>
 | 
			
		||||
  </paths>
 | 
			
		||||
 | 
			
		||||
</render-config>
 | 
			
		||||
  <!-- Contains standard messages displayed by front end -->
 | 
			
		||||
  <messages>
 | 
			
		||||
    <!-- The message displayed at the top of "top" when you're not logged in -->
 | 
			
		||||
    <welcome>
 | 
			
		||||
Welcome to the Venice Web Communities System.  To get the most out of this site, you should log in or create
 | 
			
		||||
an account, using one of the links above.
 | 
			
		||||
    </welcome>
 | 
			
		||||
 | 
			
		||||
    <!-- The headline for the welcome message -->
 | 
			
		||||
    <welcome-top>Welcome to Venice</welcome-top>
 | 
			
		||||
 | 
			
		||||
    <!-- The headline for the "currents" box -->
 | 
			
		||||
    <currents-top>Venice Currents</currents-top>
 | 
			
		||||
 | 
			
		||||
  </messages>
 | 
			
		||||
 | 
			
		||||
</render-config>
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,3 @@
 | 
			
		||||
 | 
			
		||||
# MySQL script for initializing the Venice database.
 | 
			
		||||
# Written by Eric J. Bowersox <erbo@silcom.com>
 | 
			
		||||
#---------------------------------------------------------------------------
 | 
			
		||||
@ -39,7 +38,8 @@ CREATE TABLE globals (
 | 
			
		||||
    old_posts_at_top INT NOT NULL,
 | 
			
		||||
    max_search_page INT NOT NULL,
 | 
			
		||||
    max_sig_mbr_page INT NOT NULL,
 | 
			
		||||
    max_conf_mbr_page INT NOT NULL
 | 
			
		||||
    max_conf_mbr_page INT NOT NULL,
 | 
			
		||||
    fp_posts INT NOT NULL
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
# The audit records table.  Most "major" events add a record to this table.
 | 
			
		||||
@ -87,7 +87,7 @@ CREATE TABLE users (
 | 
			
		||||
CREATE TABLE userprefs (
 | 
			
		||||
    uid INT NOT NULL PRIMARY KEY,
 | 
			
		||||
    tzid VARCHAR(64) DEFAULT 'UTC',
 | 
			
		||||
    localeid VARCHAR(64) DEFAULT 'en-US-'
 | 
			
		||||
    localeid VARCHAR(64) DEFAULT 'en_US'
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
# Indicates what the top-level "sidebox" configuration is for any given user.
 | 
			
		||||
@ -377,6 +377,7 @@ CREATE TABLE postattach (
 | 
			
		||||
    datalen INT,
 | 
			
		||||
    filename VARCHAR(255),
 | 
			
		||||
    mimetype VARCHAR(128),
 | 
			
		||||
    stgmethod SMALLINT DEFAULT 0,
 | 
			
		||||
    data MEDIUMBLOB
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@ -387,6 +388,15 @@ CREATE TABLE postdogear (
 | 
			
		||||
    PRIMARY KEY (uid, postid)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
# "Front page" publishing table.
 | 
			
		||||
CREATE TABLE postpublish (
 | 
			
		||||
    sigid INT NOT NULL,
 | 
			
		||||
    postid BIGINT NOT NULL PRIMARY KEY,
 | 
			
		||||
    by_uid INT NOT NULL,
 | 
			
		||||
    on_date DATETIME NOT NULL,
 | 
			
		||||
    INDEX display_order (on_date, postid)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
##############################################################################
 | 
			
		||||
# Set table access rights
 | 
			
		||||
##############################################################################
 | 
			
		||||
@ -409,6 +419,7 @@ GRANT INSERT, DELETE, UPDATE, SELECT ON venice.*
 | 
			
		||||
# Types of audit records.  This MUST be kept in sync with the constant definitions in
 | 
			
		||||
# com.silverwrist.venice.security.Audit!!!!
 | 
			
		||||
INSERT INTO refaudit (type, descr) VALUES
 | 
			
		||||
    (1,       'Publish Message to Front Page'),
 | 
			
		||||
    (101,     'Login OK'),
 | 
			
		||||
    (102,     'Login Failure'),
 | 
			
		||||
    (103,     'Account Created'),
 | 
			
		||||
@ -1312,8 +1323,9 @@ INSERT INTO refsigftr (ftr_code, is_default, is_locked, is_hidden, require_read,
 | 
			
		||||
##############################################################################
 | 
			
		||||
 | 
			
		||||
# Initialize the system globals table.
 | 
			
		||||
INSERT INTO globals (posts_per_page, old_posts_at_top, max_search_page, max_sig_mbr_page, max_conf_mbr_page)
 | 
			
		||||
    VALUES (20, 2, 20, 50, 50);
 | 
			
		||||
INSERT INTO globals (posts_per_page, old_posts_at_top, max_search_page, max_sig_mbr_page, max_conf_mbr_page,
 | 
			
		||||
                     fp_posts)
 | 
			
		||||
    VALUES (20, 2, 20, 50, 50, 10);
 | 
			
		||||
 | 
			
		||||
# Add the 'Anonymous Honyak' user to the users table.
 | 
			
		||||
# (Do 'SELECT * FROM users WHERE is_anon = 1' to retrieve the AC user details.)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								src/com/silverwrist/util/LocaleFactory.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/com/silverwrist/util/LocaleFactory.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.util;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
public class LocaleFactory
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private LocaleFactory()
 | 
			
		||||
  { // this object cannot be instantiated
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External static operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public static Locale createLocale(String streq)
 | 
			
		||||
  {
 | 
			
		||||
    if ((streq==null) || (streq.length()==0))
 | 
			
		||||
      return Locale.getDefault();
 | 
			
		||||
    int p1 = streq.indexOf('_');
 | 
			
		||||
    if (p1<0)
 | 
			
		||||
      return new Locale(streq,"");
 | 
			
		||||
    String x_lang = streq.substring(0,p1);
 | 
			
		||||
    int p2 = streq.indexOf('_',p1+1);
 | 
			
		||||
    if (p2<0)
 | 
			
		||||
    { // there's only one underscore - figure out what part the last part is
 | 
			
		||||
      String lastpart = streq.substring(p1+1);
 | 
			
		||||
      if (lastpart.length()==2)
 | 
			
		||||
	return new Locale(streq.substring(0,p1),lastpart);
 | 
			
		||||
      else
 | 
			
		||||
	return new Locale(streq.substring(0,p1),"",lastpart);
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    // do all three variants
 | 
			
		||||
    return new Locale(streq.substring(0,p1),streq.substring(p1+1,p2),streq.substring(p2+1));
 | 
			
		||||
 | 
			
		||||
  } // end createLocale
 | 
			
		||||
 | 
			
		||||
} // end class LocaleFactory
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * 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 Community System.
 | 
			
		||||
 * 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
 | 
			
		||||
@ -73,4 +73,8 @@ public interface TopicMessageContext
 | 
			
		||||
  public abstract void attachData(String m_type, String file, int length, InputStream data)
 | 
			
		||||
      throws AccessError, DataException;
 | 
			
		||||
 | 
			
		||||
  public abstract boolean canPublish();
 | 
			
		||||
 | 
			
		||||
  public abstract void publish() throws DataException, AccessError;
 | 
			
		||||
 | 
			
		||||
} // end interface TopicMessageContext
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,8 @@
 | 
			
		||||
package com.silverwrist.venice.core;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.TimeZone;
 | 
			
		||||
 | 
			
		||||
public interface UserContext extends SearchMode
 | 
			
		||||
{
 | 
			
		||||
@ -93,4 +95,12 @@ public interface UserContext extends SearchMode
 | 
			
		||||
 | 
			
		||||
  public abstract AdminOperations getAdminInterface() throws AccessError;
 | 
			
		||||
 | 
			
		||||
  public abstract Locale getLocale() throws DataException;
 | 
			
		||||
 | 
			
		||||
  public abstract void setLocale(Locale locale) throws DataException;
 | 
			
		||||
 | 
			
		||||
  public abstract TimeZone getTimeZone() throws DataException;
 | 
			
		||||
 | 
			
		||||
  public abstract void setTimeZone(TimeZone timezone) throws DataException;
 | 
			
		||||
 | 
			
		||||
} // end interface UserContext
 | 
			
		||||
 | 
			
		||||
@ -73,4 +73,6 @@ public interface VeniceEngine extends SearchMode
 | 
			
		||||
 | 
			
		||||
  public abstract List getMasterSideBoxList();
 | 
			
		||||
 | 
			
		||||
  public abstract List getPublishedMessages(boolean all) throws DataException;
 | 
			
		||||
 | 
			
		||||
} // end interface VeniceEngine
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,7 @@ class BackgroundConferencePurge implements Runnable
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private EngineBackend engine;
 | 
			
		||||
  private DataPool datapool;
 | 
			
		||||
  private int confid;
 | 
			
		||||
  private int num_topics;
 | 
			
		||||
@ -47,8 +48,10 @@ class BackgroundConferencePurge implements Runnable
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  BackgroundConferencePurge(DataPool datapool, int confid, int num_topics, int max_topicid)
 | 
			
		||||
  BackgroundConferencePurge(EngineBackend engine, DataPool datapool, int confid, int num_topics,
 | 
			
		||||
			    int max_topicid)
 | 
			
		||||
  {
 | 
			
		||||
    this.engine = engine;
 | 
			
		||||
    this.datapool = datapool;
 | 
			
		||||
    this.confid = confid;
 | 
			
		||||
    this.num_topics = num_topics;
 | 
			
		||||
@ -100,7 +103,7 @@ class BackgroundConferencePurge implements Runnable
 | 
			
		||||
	rs = stmt.executeQuery(sql.toString());
 | 
			
		||||
	if (!(rs.next()))
 | 
			
		||||
	  throw new InternalStateError("BackgroundConferencePurge.run screwup on post SELECT");
 | 
			
		||||
	rq.queue(new BackgroundTopicPurge(datapool,topicids[i],rs.getInt(1),rs.getLong(2)));
 | 
			
		||||
	rq.queue(new BackgroundTopicPurge(engine,datapool,topicids[i],rs.getInt(1),rs.getLong(2)));
 | 
			
		||||
 | 
			
		||||
      } // end for
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,7 @@ class BackgroundSIGPurge implements Runnable
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private EngineBackend engine;
 | 
			
		||||
  private DataPool datapool;
 | 
			
		||||
  private UserBackend user;
 | 
			
		||||
  private int sigid;
 | 
			
		||||
@ -51,9 +52,10 @@ class BackgroundSIGPurge implements Runnable
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  BackgroundSIGPurge(DataPool datapool, UserBackend user, int sigid, int num_confs, int max_confid,
 | 
			
		||||
		     Hashtable conf_objects)
 | 
			
		||||
  BackgroundSIGPurge(EngineBackend engine, DataPool datapool, UserBackend user, int sigid, int num_confs,
 | 
			
		||||
		     int max_confid, Hashtable conf_objects)
 | 
			
		||||
  {
 | 
			
		||||
    this.engine = engine;
 | 
			
		||||
    this.datapool = datapool;
 | 
			
		||||
    this.user = user;
 | 
			
		||||
    this.sigid = sigid;
 | 
			
		||||
@ -137,7 +139,7 @@ class BackgroundSIGPurge implements Runnable
 | 
			
		||||
	    rs = stmt.executeQuery(sql.toString());
 | 
			
		||||
	    if (!(rs.next()))
 | 
			
		||||
	      throw new InternalStateError("BackgroundSIGPurge.run screwup on conference SELECT");
 | 
			
		||||
	    rq.queue(new BackgroundConferencePurge(datapool,key.intValue(),rs.getInt(1),rs.getInt(2)));
 | 
			
		||||
	    rq.queue(new BackgroundConferencePurge(engine,datapool,key.intValue(),rs.getInt(1),rs.getInt(2)));
 | 
			
		||||
 | 
			
		||||
	  } // end if (have to delete conference data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ class BackgroundTopicPurge implements Runnable
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private EngineBackend engine;
 | 
			
		||||
  private DataPool datapool;
 | 
			
		||||
  private int topicid;
 | 
			
		||||
  private int num_posts;
 | 
			
		||||
@ -45,8 +46,9 @@ class BackgroundTopicPurge implements Runnable
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  BackgroundTopicPurge(DataPool datapool, int topicid, int num_posts, long max_postid)
 | 
			
		||||
  BackgroundTopicPurge(EngineBackend engine, DataPool datapool, int topicid, int num_posts, long max_postid)
 | 
			
		||||
  {
 | 
			
		||||
    this.engine = engine;
 | 
			
		||||
    this.datapool = datapool;
 | 
			
		||||
    this.topicid = topicid;
 | 
			
		||||
    this.num_posts = num_posts;
 | 
			
		||||
@ -62,7 +64,7 @@ class BackgroundTopicPurge implements Runnable
 | 
			
		||||
  public void run()
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("BackgroundTopicPurge running on topic #" + String.valueOf(topicid));
 | 
			
		||||
      logger.debug("BackgroundTopicPurge running on topic #" + topicid);
 | 
			
		||||
 | 
			
		||||
    long[] postids = new long[num_posts];  // stores the post IDs
 | 
			
		||||
    Connection conn = null;  // pooled database connection
 | 
			
		||||
@ -82,22 +84,23 @@ class BackgroundTopicPurge implements Runnable
 | 
			
		||||
 | 
			
		||||
      for (int i=0; i<posts; i++)
 | 
			
		||||
      { // remove all references to the posts in question
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM posts WHERE postid = " + String.valueOf(postids[i]) + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postdata WHERE postid = " + String.valueOf(postids[i]) + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postattach WHERE postid = " + String.valueOf(postids[i]) + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postdogear WHERE postid = " + String.valueOf(postids[i]) + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM posts WHERE postid = " + postids[i] + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postdata WHERE postid = " + postids[i] + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postattach WHERE postid = " + postids[i] + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postdogear WHERE postid = " + postids[i] + ";");
 | 
			
		||||
	if (stmt.executeUpdate("DELETE FROM postpublish WHERE postid = " + postids[i] + ";")>0)
 | 
			
		||||
	  engine.unpublish(postids[i]);
 | 
			
		||||
 | 
			
		||||
      } // end for
 | 
			
		||||
 | 
			
		||||
      // all done, Bunky!
 | 
			
		||||
      if (logger.isDebugEnabled())
 | 
			
		||||
	logger.debug("BackgroundTopicPurge complete for topic #" + String.valueOf(topicid));
 | 
			
		||||
	logger.debug("BackgroundTopicPurge complete for topic #" + topicid);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // on an error, just die
 | 
			
		||||
      logger.error("BackgroundTopicPurge FATAL EXCEPTION purging #" + String.valueOf(topicid) + ": "
 | 
			
		||||
		   + e.getMessage(),e);
 | 
			
		||||
      logger.error("BackgroundTopicPurge FATAL EXCEPTION purging #" + topicid + ": " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
 | 
			
		||||
@ -1238,7 +1238,8 @@ class ConferenceCoreData implements ConferenceData
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
    // Delete the rest of the gunk in the background; spin off another thread to handle it.
 | 
			
		||||
    BackgroundConferencePurge purger = new BackgroundConferencePurge(datapool,confid,topic_count,topic_max);
 | 
			
		||||
    BackgroundConferencePurge purger = new BackgroundConferencePurge(engine,datapool,confid,topic_count,
 | 
			
		||||
								     topic_max);
 | 
			
		||||
    Thread thrd = new Thread(purger);
 | 
			
		||||
    thrd.setPriority(Thread.NORM_PRIORITY-1);
 | 
			
		||||
    thrd.start();
 | 
			
		||||
 | 
			
		||||
@ -789,7 +789,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
 | 
			
		||||
      else
 | 
			
		||||
      { // need to insert a confsettings row
 | 
			
		||||
	sql.append("INSERT INTO confsettings (confid, uid, default_pseud) VALUES (").append(confid);
 | 
			
		||||
	sql.append(", ").append(sig.realUID()).append(", '").append(SQLUtil.encodeString(val)).append("';");
 | 
			
		||||
	sql.append(", ").append(sig.realUID()).append(", '").append(SQLUtil.encodeString(val)).append("');");
 | 
			
		||||
 | 
			
		||||
      } // end else
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * 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 Community System.
 | 
			
		||||
 * 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
 | 
			
		||||
@ -19,12 +19,24 @@ 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.db.*;
 | 
			
		||||
 | 
			
		||||
class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
{
 | 
			
		||||
  // Attributes
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Static data members
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private static Category logger = Category.getInstance(ContactInfoImpl.class.getName());
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Attributes
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private int contactid;                 // ID of this contact record (-1 = new)
 | 
			
		||||
  private String given_name;             // given name ("first name")
 | 
			
		||||
  private String family_name;            // family name ("last name")
 | 
			
		||||
@ -53,6 +65,11 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
  private java.util.Date last_update;    // date of last update
 | 
			
		||||
  private boolean is_modified = false;   // have we modified this ContactInfo?
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructors
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructs a new blank <CODE>ContactInfoImpl</CODE> object.
 | 
			
		||||
   *
 | 
			
		||||
@ -60,6 +77,8 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
   */
 | 
			
		||||
  ContactInfoImpl(int owner_uid)
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("new ContactInfoImpl (empty) for UID = " + owner_uid);
 | 
			
		||||
    makeEmpty(owner_uid,-1);
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
@ -72,6 +91,8 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
   */
 | 
			
		||||
  ContactInfoImpl(int owner_uid, int owner_sigid)
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("new ContactInfoImpl (empty) for UID = " + owner_uid + ", SIGID = " + owner_sigid);
 | 
			
		||||
    makeEmpty(owner_uid,owner_sigid);
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
@ -85,6 +106,8 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
   */
 | 
			
		||||
  ContactInfoImpl(DataPool dp, int contactid) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("new ContactInfoImpl (loading CID " + contactid + ")");
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
@ -95,6 +118,7 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // turn SQLExceptions at this level into DataExceptions
 | 
			
		||||
      logger.error("DB error loading contact ID " + contactid + ": " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("Unable to look up contact info: " + e.getMessage(),e);
 | 
			
		||||
      
 | 
			
		||||
    } // end catch
 | 
			
		||||
@ -107,6 +131,11 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Internal functions
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private void makeEmpty(int owner_uid, int owner_sigid)
 | 
			
		||||
  {
 | 
			
		||||
    this.contactid = -1;
 | 
			
		||||
@ -180,18 +209,28 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
	last_update = SQLUtil.getFullDateTime(rs,"lastupdate");
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
      else  // contact was not found
 | 
			
		||||
      else
 | 
			
		||||
      { // contact was not found
 | 
			
		||||
	logger.error("contact ID " + contactid + " not found in database");
 | 
			
		||||
	throw new DataException("Contact was not found.");
 | 
			
		||||
 | 
			
		||||
      } // end else
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // map all SQLExceptions into DataExceptions
 | 
			
		||||
      logger.error("DB error loading contact ID " + contactid + ": " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("Unable to look up contact info: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
  } // end loadData
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface ContactInfo
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public int getContactID()
 | 
			
		||||
  {
 | 
			
		||||
    return contactid;
 | 
			
		||||
@ -559,6 +598,11 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
 | 
			
		||||
  } // end getModified
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface Stashable
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public int getStashableUID()
 | 
			
		||||
  {
 | 
			
		||||
    return getOwnerUID();
 | 
			
		||||
@ -567,6 +611,8 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
 | 
			
		||||
  public void stash(Connection conn) throws DataException, SQLException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("stashing contact ID " + contactid);
 | 
			
		||||
    java.util.Date update = null;
 | 
			
		||||
    Statement stmt = conn.createStatement();
 | 
			
		||||
    StringBuffer buf;
 | 
			
		||||
@ -653,10 +699,19 @@ class ContactInfoImpl implements ContactInfo, Stashable
 | 
			
		||||
	int new_contactid;
 | 
			
		||||
	ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
 | 
			
		||||
	if (rs.next())
 | 
			
		||||
	{ // found the contact ID...
 | 
			
		||||
	  new_contactid = rs.getInt(1);
 | 
			
		||||
	  if (logger.isDebugEnabled())
 | 
			
		||||
	    logger.debug("created new contact ID " + new_contactid);
 | 
			
		||||
 | 
			
		||||
	} // end if
 | 
			
		||||
	else
 | 
			
		||||
	{ // error reading back the contact ID
 | 
			
		||||
	  logger.error("unable to read back contact ID");
 | 
			
		||||
	  throw new DataException("unable to read back new contact ID");
 | 
			
		||||
 | 
			
		||||
	} // end else
 | 
			
		||||
 | 
			
		||||
	// and patch the database table so we know what our contact ID is
 | 
			
		||||
	buf.setLength(0);
 | 
			
		||||
	if (owner_sigid>=0)
 | 
			
		||||
 | 
			
		||||
@ -36,6 +36,7 @@ public interface EngineBackend
 | 
			
		||||
  public static final int IP_MAXSEARCHRETURN = 2;
 | 
			
		||||
  public static final int IP_MAXSIGMEMBERDISPLAY = 3;
 | 
			
		||||
  public static final int IP_MAXCONFMEMBERDISPLAY = 4;
 | 
			
		||||
  public static final int IP_NUMFRONTPAGEPOSTS = 5;
 | 
			
		||||
 | 
			
		||||
  public abstract SimpleEmailer createEmailer();
 | 
			
		||||
 | 
			
		||||
@ -83,4 +84,10 @@ public interface EngineBackend
 | 
			
		||||
 | 
			
		||||
  public abstract SideBoxDescriptor getMasterSideBoxDescriptor(int id);
 | 
			
		||||
 | 
			
		||||
  public abstract void startPublish();
 | 
			
		||||
 | 
			
		||||
  public abstract void publishNew(PublishedMessageImpl pubmsg);
 | 
			
		||||
 | 
			
		||||
  public abstract void unpublish(long postid);
 | 
			
		||||
 | 
			
		||||
} // end interface EngineBackend
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										426
									
								
								src/com/silverwrist/venice/core/impl/PublishedMessageImpl.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										426
									
								
								src/com/silverwrist/venice/core/impl/PublishedMessageImpl.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,426 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.core.impl;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.sql.*;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import org.apache.log4j.*;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.db.*;
 | 
			
		||||
import com.silverwrist.venice.core.*;
 | 
			
		||||
 | 
			
		||||
class PublishedMessageImpl implements TopicMessageContext
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Static data members
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private static Category logger = Category.getInstance(PublishedMessageImpl.class.getName());
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Attributes
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private DataPool datapool;
 | 
			
		||||
  private long postid;
 | 
			
		||||
  private long parent;
 | 
			
		||||
  private int num;
 | 
			
		||||
  private int linecount;
 | 
			
		||||
  private int creator_uid;
 | 
			
		||||
  private java.util.Date posted;
 | 
			
		||||
  private String pseud;
 | 
			
		||||
  private String creator_cache = null;
 | 
			
		||||
  private String text_cache = null;
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructors
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  PublishedMessageImpl(DataPool datapool, long postid, long parent, int num, int linecount, int creator_uid,
 | 
			
		||||
		       java.util.Date posted, String pseud, String creator_cache, String text_cache)
 | 
			
		||||
  {
 | 
			
		||||
    this.datapool = datapool;
 | 
			
		||||
    this.postid = postid;
 | 
			
		||||
    this.parent = parent;
 | 
			
		||||
    this.num = num;
 | 
			
		||||
    this.linecount = linecount;
 | 
			
		||||
    this.creator_uid = creator_uid;
 | 
			
		||||
    this.posted = posted;
 | 
			
		||||
    this.pseud = pseud;
 | 
			
		||||
    this.creator_cache = creator_cache;
 | 
			
		||||
    this.text_cache = text_cache;
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  protected PublishedMessageImpl(DataPool datapool, long postid, long parent, int num, int linecount,
 | 
			
		||||
				 int creator_uid, java.util.Date posted, String pseud)
 | 
			
		||||
  {
 | 
			
		||||
    this.datapool = datapool;
 | 
			
		||||
    this.postid = postid;
 | 
			
		||||
    this.parent = parent;
 | 
			
		||||
    this.num = num;
 | 
			
		||||
    this.linecount = linecount;
 | 
			
		||||
    this.creator_uid = creator_uid;
 | 
			
		||||
    this.posted = posted;
 | 
			
		||||
    this.pseud = pseud;
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Internal functions
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private static String quickGetUserName(Connection conn, int uid) throws SQLException
 | 
			
		||||
  {
 | 
			
		||||
    Statement stmt = conn.createStatement();
 | 
			
		||||
    ResultSet rs = stmt.executeQuery("SELECT username FROM users WHERE uid = " + String.valueOf(uid) + ";");
 | 
			
		||||
    if (rs.next())
 | 
			
		||||
      return rs.getString(1);
 | 
			
		||||
    else
 | 
			
		||||
      return "(unknown)";
 | 
			
		||||
 | 
			
		||||
  } // end quickGetUserName
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface TopicMessageContext
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public long getPostID()
 | 
			
		||||
  {
 | 
			
		||||
    return postid;
 | 
			
		||||
 | 
			
		||||
  } // end getPostID
 | 
			
		||||
 | 
			
		||||
  public long getParentPostID()
 | 
			
		||||
  {
 | 
			
		||||
    return parent;
 | 
			
		||||
 | 
			
		||||
  } // end getParentPostID
 | 
			
		||||
 | 
			
		||||
  public int getPostNumber()
 | 
			
		||||
  {
 | 
			
		||||
    return num;
 | 
			
		||||
 | 
			
		||||
  } // end getPostNumber
 | 
			
		||||
 | 
			
		||||
  public int getNumLines()
 | 
			
		||||
  {
 | 
			
		||||
    return linecount;
 | 
			
		||||
 | 
			
		||||
  } // end getNumLines
 | 
			
		||||
 | 
			
		||||
  public int getCreatorUID()
 | 
			
		||||
  {
 | 
			
		||||
    return creator_uid;
 | 
			
		||||
 | 
			
		||||
  } // end getCreatorUID
 | 
			
		||||
 | 
			
		||||
  public String getCreatorName() throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (creator_cache==null)
 | 
			
		||||
    { // we don't have the user name yet, get it out of the database
 | 
			
		||||
      Connection conn = null;
 | 
			
		||||
 | 
			
		||||
      try
 | 
			
		||||
      { // use a database connection to get the user name
 | 
			
		||||
	conn = datapool.getConnection();
 | 
			
		||||
	creator_cache = quickGetUserName(conn,creator_uid);
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (SQLException e)
 | 
			
		||||
      { // turn this into a DataException
 | 
			
		||||
	logger.error("DB error reading user name: " + e.getMessage(),e);
 | 
			
		||||
	throw new DataException("unable to retrieve user name: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
      finally
 | 
			
		||||
      { // make sure we release the connection before we go
 | 
			
		||||
	if (conn!=null)
 | 
			
		||||
	  datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
      } // end finally
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    return creator_cache;
 | 
			
		||||
 | 
			
		||||
  } // end getCreatorName
 | 
			
		||||
 | 
			
		||||
  public java.util.Date getPostDate()
 | 
			
		||||
  {
 | 
			
		||||
    return posted;
 | 
			
		||||
 | 
			
		||||
  } // end getPostDate
 | 
			
		||||
 | 
			
		||||
  public boolean isHidden()
 | 
			
		||||
  {
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  } // end isHidden
 | 
			
		||||
 | 
			
		||||
  public boolean isScribbled()
 | 
			
		||||
  {
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  } // end isScribbled
 | 
			
		||||
 | 
			
		||||
  public boolean isNuked()
 | 
			
		||||
  {
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  } // end isNuked
 | 
			
		||||
 | 
			
		||||
  public java.util.Date getScribbleDate()
 | 
			
		||||
  {
 | 
			
		||||
    return null;
 | 
			
		||||
 | 
			
		||||
  } // end getScribbleDate
 | 
			
		||||
 | 
			
		||||
  public String getPseud()
 | 
			
		||||
  {
 | 
			
		||||
    return pseud;
 | 
			
		||||
 | 
			
		||||
  } // end getPseud
 | 
			
		||||
 | 
			
		||||
  public String getBodyText() throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (text_cache==null)
 | 
			
		||||
    { // we don't have the body text yet, go get it
 | 
			
		||||
      Connection conn = null;
 | 
			
		||||
 | 
			
		||||
      try
 | 
			
		||||
      { // use a database connection to get the body text
 | 
			
		||||
	conn = datapool.getConnection();
 | 
			
		||||
 | 
			
		||||
	Statement stmt = conn.createStatement();
 | 
			
		||||
	ResultSet rs = stmt.executeQuery("SELECT data FROM postdata WHERE postid = "
 | 
			
		||||
					 + String.valueOf(postid) + ";");
 | 
			
		||||
	if (rs.next())
 | 
			
		||||
	  text_cache = rs.getString(1);
 | 
			
		||||
	else
 | 
			
		||||
	  return "Data Missing";  // FUTURE: throw an exception?
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (SQLException e)
 | 
			
		||||
      { // turn this into a DataException
 | 
			
		||||
	logger.error("DB error reading post data: " + e.getMessage(),e);
 | 
			
		||||
	throw new DataException("unable to retrieve post data: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
      finally
 | 
			
		||||
      { // make sure we release the connection before we go
 | 
			
		||||
	if (conn!=null)
 | 
			
		||||
	  datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
      } // end finally
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    return text_cache;
 | 
			
		||||
 | 
			
		||||
  } // end getBodyCache
 | 
			
		||||
 | 
			
		||||
  public boolean hasAttachment()
 | 
			
		||||
  {
 | 
			
		||||
    return false;  // FUTURE: allow publishing paperclips?
 | 
			
		||||
 | 
			
		||||
  } // end hasAttachment
 | 
			
		||||
 | 
			
		||||
  public String getAttachmentType()
 | 
			
		||||
  {
 | 
			
		||||
    return null;  // FUTURE: allow publishing paperclips?
 | 
			
		||||
 | 
			
		||||
  } // end getAttachmentType
 | 
			
		||||
 | 
			
		||||
  public String getAttachmentFilename()
 | 
			
		||||
  {
 | 
			
		||||
    return null;  // FUTURE: allow publishing paperclips?
 | 
			
		||||
 | 
			
		||||
  } // end getAttachmentFilename
 | 
			
		||||
 | 
			
		||||
  public int getAttachmentLength()
 | 
			
		||||
  {
 | 
			
		||||
    return 0;  // FUTURE: allow publishing paperclips?
 | 
			
		||||
 | 
			
		||||
  } // end getAttachmentLength
 | 
			
		||||
 | 
			
		||||
  public InputStream getAttachmentData() throws AccessError, DataException
 | 
			
		||||
  {
 | 
			
		||||
    // FUTURE: allow publishing paperclips?
 | 
			
		||||
    throw new AccessError("There is no attachment data for this message.");
 | 
			
		||||
 | 
			
		||||
  } // end getAttachmentData
 | 
			
		||||
 | 
			
		||||
  public boolean canHide()
 | 
			
		||||
  {
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  } // end canHide
 | 
			
		||||
 | 
			
		||||
  public boolean canScribble()
 | 
			
		||||
  {
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  } // end canScribble
 | 
			
		||||
 | 
			
		||||
  public boolean canNuke()
 | 
			
		||||
  {
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  } // end canNuke
 | 
			
		||||
 | 
			
		||||
  public void setHidden(boolean flag) throws DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    throw new AccessError("You are not permitted to change the hidden status of this message.");
 | 
			
		||||
 | 
			
		||||
  } // end setHidden
 | 
			
		||||
 | 
			
		||||
  public void scribble() throws DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    throw new AccessError("You are not permitted to scribble this message.");
 | 
			
		||||
 | 
			
		||||
  } // end scribble
 | 
			
		||||
 | 
			
		||||
  public void nuke() throws DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    throw new AccessError("You are not permitted to nuke this message.");
 | 
			
		||||
 | 
			
		||||
  } // end nuke
 | 
			
		||||
 | 
			
		||||
  public void attachData(String m_type, String file, int length, InputStream data)
 | 
			
		||||
      throws AccessError, DataException
 | 
			
		||||
  {
 | 
			
		||||
    throw new AccessError("You are not permitted to add an attachment to this message.");
 | 
			
		||||
 | 
			
		||||
  } // end attachData
 | 
			
		||||
 | 
			
		||||
  public boolean canPublish()
 | 
			
		||||
  {
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  } // end canPublish
 | 
			
		||||
 | 
			
		||||
  public void publish() throws DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    throw new DataException("Cannot publish a message that has already been published.");
 | 
			
		||||
 | 
			
		||||
  } // end publish
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Static operations usable only within package
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  static void backfillCache(List cache_list, int desired_size, DataPool datapool) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // get a database connection
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      // create the statement to retrieve the post information
 | 
			
		||||
      StringBuffer sql =
 | 
			
		||||
	  new StringBuffer("SELECT p.postid, q.parent, q.num, q.linecount, q.creator_uid, q.posted, "
 | 
			
		||||
			   + "q.pseud FROM postpublish p, posts q WHERE p.postid = q.postid "
 | 
			
		||||
			   + "ORDER BY p.on_date DESC, p.postid ASC LIMIT ");
 | 
			
		||||
      sql.append(cache_list.size()).append(", ").append(desired_size-cache_list.size()).append(';');
 | 
			
		||||
 | 
			
		||||
      // execute the statement!
 | 
			
		||||
      ResultSet rs = stmt.executeQuery(sql.toString());
 | 
			
		||||
      while (rs.next())
 | 
			
		||||
	cache_list.add(new PublishedMessageImpl(datapool,rs.getLong(1),rs.getLong(2),rs.getInt(3),rs.getInt(4),
 | 
			
		||||
						rs.getInt(5),SQLUtil.getFullDateTime(rs,6),rs.getString(7)));
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // error retrieving post information
 | 
			
		||||
      logger.error("DB error reading post information: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to retrieve post information: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection before we go
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end backfillCache
 | 
			
		||||
 | 
			
		||||
  static void backfillReturn(List return_list, DataPool datapool) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // get a database connection
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      // How many posts have been published anyway?
 | 
			
		||||
      ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM postpublish;");
 | 
			
		||||
      if (!(rs.next()))
 | 
			
		||||
	throw new InternalStateError("Count query screwup in PublishedMessageImpl.backfillReturn");
 | 
			
		||||
      if (rs.getInt(1)<=return_list.size())
 | 
			
		||||
	return;  // nothing to do here!
 | 
			
		||||
 | 
			
		||||
      // execute the statement to retrieve the post information
 | 
			
		||||
      final String sql = "SELECT p.postid, q.parent, q.num, q.linecount, q.creator_uid, q.posted, q.pseud "
 | 
			
		||||
	               + "FROM postpublish p, posts q WHERE p.postid = q.postid ORDER BY p.on_date DESC, "
 | 
			
		||||
	               + "p.postid ASC;";
 | 
			
		||||
      rs = stmt.executeQuery(sql);
 | 
			
		||||
 | 
			
		||||
      // append to the output list
 | 
			
		||||
      int ctr = return_list.size();
 | 
			
		||||
      while (rs.next())
 | 
			
		||||
      { // we need to skip the first batch of output, because it's cached
 | 
			
		||||
	if ((ctr--)<=0)
 | 
			
		||||
	{ // append context, please
 | 
			
		||||
	  TopicMessageContext ctxt = 
 | 
			
		||||
	      new PublishedMessageImpl(datapool,rs.getLong(1),rs.getLong(2),rs.getInt(3),rs.getInt(4),
 | 
			
		||||
				       rs.getInt(5),SQLUtil.getFullDateTime(rs,6),rs.getString(7));
 | 
			
		||||
	  return_list.add(ctxt);
 | 
			
		||||
 | 
			
		||||
	} // end if
 | 
			
		||||
 | 
			
		||||
      } // end while
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // error retrieving post information
 | 
			
		||||
      logger.error("DB error reading post information: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to retrieve post information: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection before we go
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end backfillReturn
 | 
			
		||||
 | 
			
		||||
} // end class PublishedMessageImpl
 | 
			
		||||
@ -1852,7 +1852,8 @@ class SIGCoreData implements SIGData, SIGDataBackend
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
    // Delete the rest of the gunk in the background; use another thread to do it.
 | 
			
		||||
    BackgroundSIGPurge purger = new BackgroundSIGPurge(datapool,user,sigid,conf_count,conf_max,conf_objects);
 | 
			
		||||
    BackgroundSIGPurge purger = new BackgroundSIGPurge(engine,datapool,user,sigid,conf_count,conf_max,
 | 
			
		||||
						       conf_objects);
 | 
			
		||||
    Thread thrd = new Thread(purger);
 | 
			
		||||
    thrd.setPriority(Thread.NORM_PRIORITY-1);
 | 
			
		||||
    thrd.start();
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * 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 Community System.
 | 
			
		||||
 * 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
 | 
			
		||||
@ -24,6 +24,7 @@ import org.apache.log4j.*;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.db.*;
 | 
			
		||||
import com.silverwrist.venice.security.AuditRecord;
 | 
			
		||||
import com.silverwrist.venice.security.Capability;
 | 
			
		||||
import com.silverwrist.venice.core.*;
 | 
			
		||||
 | 
			
		||||
class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
@ -123,7 +124,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
  private static String quickGetUserName(Connection conn, int uid) throws SQLException
 | 
			
		||||
  {
 | 
			
		||||
    Statement stmt = conn.createStatement();
 | 
			
		||||
    ResultSet rs = stmt.executeQuery("SELECT username FROM users WHERE uid = " + String.valueOf(uid) + ";");
 | 
			
		||||
    ResultSet rs = stmt.executeQuery("SELECT username FROM users WHERE uid = " + uid + ";");
 | 
			
		||||
    if (rs.next())
 | 
			
		||||
      return rs.getString(1);
 | 
			
		||||
    else
 | 
			
		||||
@ -297,8 +298,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
	if (scribble_date==null)
 | 
			
		||||
	{ // let's go get the body text!
 | 
			
		||||
	  Statement stmt = conn.createStatement();
 | 
			
		||||
	  ResultSet rs = stmt.executeQuery("SELECT data FROM postdata WHERE postid = "
 | 
			
		||||
					   + String.valueOf(postid) + ";");
 | 
			
		||||
	  ResultSet rs = stmt.executeQuery("SELECT data FROM postdata WHERE postid = " + postid + ";");
 | 
			
		||||
	  if (rs.next())
 | 
			
		||||
	    text_cache = rs.getString(1);
 | 
			
		||||
	  else
 | 
			
		||||
@ -508,8 +508,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
 | 
			
		||||
      // record what we did in an audit record
 | 
			
		||||
      ar = new AuditRecord(AuditRecord.HIDE_MESSAGE,conf.realUID(),conf.userRemoteAddress(),
 | 
			
		||||
			   conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",post="
 | 
			
		||||
			   + String.valueOf(postid),flag ? "hide" : "unhide");
 | 
			
		||||
			   conf.realSIGID(),"conf=" + conf.realConfID() + ",post=" + postid,
 | 
			
		||||
			   flag ? "hide" : "unhide");
 | 
			
		||||
      
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
@ -562,7 +562,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      // lock the tables we reference
 | 
			
		||||
      stmt.executeUpdate("LOCK TABLES posts WRITE, postdata WRITE, postattach WRITE;");
 | 
			
		||||
      stmt.executeUpdate("LOCK TABLES posts WRITE, postdata WRITE, postattach WRITE, postpublish WRITE;");
 | 
			
		||||
      try
 | 
			
		||||
      { // first, make sure we have the right status for our post
 | 
			
		||||
	refresh(conn);
 | 
			
		||||
@ -581,8 +581,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
	stmt.executeUpdate(sql.toString());
 | 
			
		||||
 | 
			
		||||
	// Determine if we need to "rub out" the post before we delete it.
 | 
			
		||||
	ResultSet rs = stmt.executeQuery("SELECT LENGTH(data) FROM postdata WHERE postid = "
 | 
			
		||||
					 + String.valueOf(postid) + ";");
 | 
			
		||||
	ResultSet rs = stmt.executeQuery("SELECT LENGTH(data) FROM postdata WHERE postid = " + postid + ";");
 | 
			
		||||
	if (rs.next())
 | 
			
		||||
	{ // use this data to overwrite the post with X's
 | 
			
		||||
	  int len = rs.getInt(1);
 | 
			
		||||
@ -617,6 +616,12 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
	sql.append("DELETE FROM postattach WHERE postid = ").append(postid).append(';');
 | 
			
		||||
	stmt.executeUpdate(sql.toString());
 | 
			
		||||
 | 
			
		||||
	// Un-publish the posting.
 | 
			
		||||
	sql.setLength(0);
 | 
			
		||||
	sql.append("DELETE FROM postpublish WHERE postid = ").append(postid).append(';');
 | 
			
		||||
	if (stmt.executeUpdate(sql.toString())>0)
 | 
			
		||||
	  engine.unpublish(postid);
 | 
			
		||||
 | 
			
		||||
	// Update our internal data fields.
 | 
			
		||||
	linecount = 0;
 | 
			
		||||
	hidden = false;
 | 
			
		||||
@ -635,8 +640,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
 | 
			
		||||
      // record what we did in an audit record
 | 
			
		||||
      ar = new AuditRecord(AuditRecord.SCRIBBLE_MESSAGE,conf.realUID(),conf.userRemoteAddress(),
 | 
			
		||||
			   conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",post="
 | 
			
		||||
			   + String.valueOf(postid));
 | 
			
		||||
			   conf.realSIGID(),"conf=" + conf.realConfID() + ",post=" + postid);
 | 
			
		||||
      
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
@ -687,7 +691,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      // lock the tables we reference
 | 
			
		||||
      stmt.executeUpdate("LOCK TABLES posts WRITE, postdata WRITE, postattach WRITE, postdogear WRITE;");
 | 
			
		||||
      stmt.executeUpdate("LOCK TABLES posts WRITE, postdata WRITE, postattach WRITE, postdogear WRITE, "
 | 
			
		||||
			 + "postpublish WRITE;");
 | 
			
		||||
 | 
			
		||||
      try
 | 
			
		||||
      { // first, make sure we have the right status for our post
 | 
			
		||||
@ -696,10 +701,12 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
	  return;  // nuking a nuked post is futile
 | 
			
		||||
 | 
			
		||||
	// Delete any and all references to this post!
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM posts WHERE postid = " + String.valueOf(postid) + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postdata WHERE postid = " + String.valueOf(postid) + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postattach WHERE postid = " + String.valueOf(postid) + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postdogear WHERE postid = " + String.valueOf(postid) + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM posts WHERE postid = " + postid + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postdata WHERE postid = " + postid + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postattach WHERE postid = " + postid + ";");
 | 
			
		||||
	stmt.executeUpdate("DELETE FROM postdogear WHERE postid = " + postid + ";");
 | 
			
		||||
	if (stmt.executeUpdate("DELETE FROM postpublish WHERE postid = " + postid + ";")>0)
 | 
			
		||||
	  engine.unpublish(postid);
 | 
			
		||||
 | 
			
		||||
	// Update our internal variables.
 | 
			
		||||
	linecount = 0;
 | 
			
		||||
@ -726,8 +733,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
 | 
			
		||||
      // record what we did in an audit record
 | 
			
		||||
      ar = new AuditRecord(AuditRecord.NUKE_MESSAGE,conf.realUID(),conf.userRemoteAddress(),
 | 
			
		||||
			   conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",post="
 | 
			
		||||
			   + String.valueOf(postid));
 | 
			
		||||
			   conf.realSIGID(),"conf=" + conf.realConfID() + ",post=" + postid);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
@ -803,9 +809,9 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
    } // end if
 | 
			
		||||
    else if (length>MAX_ATTACH)
 | 
			
		||||
    { // the attachment is too damn long!
 | 
			
		||||
      logger.error("attachment is too long (" + String.valueOf(length) + " bytes)");
 | 
			
		||||
      throw new AccessError("The attachment is too long to store.  Maximum available length is "
 | 
			
		||||
			    + String.valueOf(MAX_ATTACH) + " bytes.");
 | 
			
		||||
      logger.error("attachment is too long (" + length + " bytes)");
 | 
			
		||||
      throw new AccessError("The attachment is too long to store.  Maximum available length is " + MAX_ATTACH
 | 
			
		||||
			    + " bytes.");
 | 
			
		||||
 | 
			
		||||
    } // end else if
 | 
			
		||||
 | 
			
		||||
@ -844,9 +850,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
 | 
			
		||||
      // Generate an audit record indicating what we did.
 | 
			
		||||
      ar = new AuditRecord(AuditRecord.UPLOAD_ATTACHMENT,conf.realUID(),conf.userRemoteAddress(),
 | 
			
		||||
			   conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",post="
 | 
			
		||||
			   + String.valueOf(postid),"len=" + String.valueOf(length) + ",type=" + m_type
 | 
			
		||||
			   + ",name=" + file);
 | 
			
		||||
			   conf.realSIGID(),"conf=" + conf.realConfID() + ",post=" + postid,
 | 
			
		||||
			   "len=" + length + ",type=" + m_type + ",name=" + file);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
@ -876,6 +881,136 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
 | 
			
		||||
  } // end attachData
 | 
			
		||||
 | 
			
		||||
  public boolean canPublish()
 | 
			
		||||
  {
 | 
			
		||||
    if (!(Capability.canPublishToFrontPage(conf.realBaseLevel())))
 | 
			
		||||
      return false;  // must be a sysadmin to publish
 | 
			
		||||
    if ((scribble_date!=null) || nuked)
 | 
			
		||||
      return false;  // cannot publish a scribbled or nuked message
 | 
			
		||||
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // get a database connection
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      // see if the post has already been published
 | 
			
		||||
      ResultSet rs = stmt.executeQuery("SELECT by_uid FROM postpublish WHERE postid = " + postid
 | 
			
		||||
				       + " LIMIT 1;");
 | 
			
		||||
      return !(rs.next());
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // just trap SQL exceptions and log them
 | 
			
		||||
      logger.error("SQL exception in TopicMessageUserContextImpl.canPublish: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection before we go
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
    return false;  // assume we can't
 | 
			
		||||
 | 
			
		||||
  } // end canPublish
 | 
			
		||||
 | 
			
		||||
  public void publish() throws DataException, AccessError
 | 
			
		||||
  {
 | 
			
		||||
    if (!(Capability.canPublishToFrontPage(conf.realBaseLevel())))
 | 
			
		||||
    { // you aren't allowed to publish - naughty naughty!
 | 
			
		||||
      logger.error("unable to publish because we're not allowed");
 | 
			
		||||
      throw new AccessError("You are not permitted to publish postings to the front page.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    if (nuked)
 | 
			
		||||
    { // we can't publish a nuked message!
 | 
			
		||||
      logger.error("unable to publish because message nuked");
 | 
			
		||||
      throw new DataException("Cannot publish a message that has been nuked.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    if (scribble_date!=null)
 | 
			
		||||
    { // we can't publish a scribbled message!
 | 
			
		||||
      logger.error("unable to publish because message scribbled");
 | 
			
		||||
      throw new DataException("Cannot publish a message that has been scribbled.");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
    AuditRecord ar = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // get a database connection
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      // see if post has already been published
 | 
			
		||||
      ResultSet rs = stmt.executeQuery("SELECT by_uid FROM postpublish WHERE postid = " + postid
 | 
			
		||||
				       + " LIMIT 1;");
 | 
			
		||||
      if (rs.next())  // can't do it, friend!
 | 
			
		||||
	throw new DataException("This posting has already been published.");
 | 
			
		||||
 | 
			
		||||
      boolean done = false;
 | 
			
		||||
      engine.startPublish();
 | 
			
		||||
 | 
			
		||||
      try
 | 
			
		||||
      { // insert the post reference into the database
 | 
			
		||||
	StringBuffer sql =
 | 
			
		||||
	    new StringBuffer("INSERT INTO postpublish (sigid, postid, by_uid, on_date) VALUES (");
 | 
			
		||||
	sql.append(conf.realSIGID()).append(", ").append(postid).append(", ").append(conf.realUID());
 | 
			
		||||
	java.util.Date now = new java.util.Date();
 | 
			
		||||
	sql.append(", '").append(SQLUtil.encodeDate(now)).append("');");
 | 
			
		||||
	stmt.executeUpdate(sql.toString());
 | 
			
		||||
 | 
			
		||||
	// generate an audit record indicating what we've done
 | 
			
		||||
	ar = new AuditRecord(AuditRecord.PUBLISH_POST,conf.realUID(),conf.userRemoteAddress(),
 | 
			
		||||
			     conf.realSIGID(),"conf=" + conf.realConfID() + ",post=" + postid);
 | 
			
		||||
 | 
			
		||||
	// establish cached data object for front page
 | 
			
		||||
	engine.publishNew(new PublishedMessageImpl(datapool,postid,parent,num,linecount,creator_uid,
 | 
			
		||||
						   posted,pseud,creator_cache,text_cache));
 | 
			
		||||
	done = true;
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      finally
 | 
			
		||||
      { // make sure to release the lock if we goofed in here
 | 
			
		||||
	if (!done)
 | 
			
		||||
	  engine.publishNew(null);
 | 
			
		||||
 | 
			
		||||
      } // end finally
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // just trap SQL exceptions and log them
 | 
			
		||||
      logger.error("unable to publish posting: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to publish posting: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection before we go
 | 
			
		||||
      try
 | 
			
		||||
      { // save off the audit record before we go, though
 | 
			
		||||
	if ((ar!=null) && (conn!=null))
 | 
			
		||||
	  ar.store(conn);
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (SQLException e)
 | 
			
		||||
      { // we couldn't store the audit record!
 | 
			
		||||
	logger.error("DB error saving audit record: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end publish
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External static operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
@ -885,9 +1020,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
			       int post_low, int post_high) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("loadMessageRange for conf # " + String.valueOf(conf.realConfID()) + ", topic #"
 | 
			
		||||
		   + String.valueOf(topicid) + ", range [" + String.valueOf(post_low) + ", "
 | 
			
		||||
		   + String.valueOf(post_high) + "]");
 | 
			
		||||
      logger.debug("loadMessageRange for conf # " + conf.realConfID() + ", topic #" + topicid + ", range ["
 | 
			
		||||
		   + post_low + ", " + post_high + "]");
 | 
			
		||||
 | 
			
		||||
    Vector rc = new Vector();
 | 
			
		||||
    Connection conn = null;      // pooled database connection
 | 
			
		||||
@ -942,8 +1076,8 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
					 int topicid, int message_num) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("loadMessage for conf # " + String.valueOf(conf.realConfID()) + ", topic #"
 | 
			
		||||
		   + String.valueOf(topicid) + ", message " + String.valueOf(message_num));
 | 
			
		||||
      logger.debug("loadMessage for conf # " + conf.realConfID() + ", topic #" + topicid + ", message "
 | 
			
		||||
		   + message_num);
 | 
			
		||||
 | 
			
		||||
    Connection conn = null;      // pooled database connection
 | 
			
		||||
 | 
			
		||||
@ -993,8 +1127,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext
 | 
			
		||||
					long postid) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("getMessage for conf # " + String.valueOf(conf.realConfID()) + ", post #"
 | 
			
		||||
		   + String.valueOf(postid));
 | 
			
		||||
      logger.debug("getMessage for conf # " + conf.realConfID() + ", post #" + postid);
 | 
			
		||||
 | 
			
		||||
    Connection conn = null;      // pooled database connection
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -880,7 +880,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
    // Delete the rest of the gunk in the background; spin off another thread to handle it.
 | 
			
		||||
    BackgroundTopicPurge purger = new BackgroundTopicPurge(datapool,topicid,post_count,post_max);
 | 
			
		||||
    BackgroundTopicPurge purger = new BackgroundTopicPurge(engine,datapool,topicid,post_count,post_max);
 | 
			
		||||
    Thread thrd = new Thread(purger);
 | 
			
		||||
    thrd.setPriority(Thread.NORM_PRIORITY-1);
 | 
			
		||||
    thrd.start();
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.sql.*;
 | 
			
		||||
import org.apache.log4j.*;
 | 
			
		||||
import com.silverwrist.util.LocaleFactory;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.*;
 | 
			
		||||
import com.silverwrist.venice.core.*;
 | 
			
		||||
@ -59,6 +60,8 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
  private String my_email = null;          // my email address (cached)
 | 
			
		||||
  private String my_pseud = null;          // my pseud (cached)
 | 
			
		||||
  private String full_name = null;         // my full name (cached)
 | 
			
		||||
  private Locale my_locale = null;         // my default locale (cached)
 | 
			
		||||
  private TimeZone my_tz = null;           // my default timezone (cached)
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
@ -84,6 +87,12 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
    username = null;
 | 
			
		||||
    created = null;
 | 
			
		||||
    last_access = null;
 | 
			
		||||
    description = null;
 | 
			
		||||
    my_email = null;
 | 
			
		||||
    my_pseud = null;
 | 
			
		||||
    full_name = null;
 | 
			
		||||
    my_locale = null;
 | 
			
		||||
    my_tz = null;
 | 
			
		||||
 | 
			
		||||
  } // end finalize
 | 
			
		||||
 | 
			
		||||
@ -108,18 +117,64 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
    // skip field "passreminder"
 | 
			
		||||
    description = rs.getString("description");
 | 
			
		||||
 | 
			
		||||
    // purge any "cached" fields that may be left over
 | 
			
		||||
    my_email = null;
 | 
			
		||||
    my_pseud = null;
 | 
			
		||||
    full_name = null;
 | 
			
		||||
    my_locale = null;
 | 
			
		||||
    my_tz = null;
 | 
			
		||||
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
    { // spit it all out to debug info
 | 
			
		||||
      logger.debug("Loaded: UID " + String.valueOf(uid) + ", username \"" + username + "\", contactid "
 | 
			
		||||
		   + String.valueOf(contactid));
 | 
			
		||||
      logger.debug("...is_anon " + String.valueOf(is_anon) + ", email_verified "
 | 
			
		||||
		   + String.valueOf(email_verified));
 | 
			
		||||
      logger.debug("... level " + String.valueOf(level));
 | 
			
		||||
      logger.debug("Loaded: UID " + uid + ", username \"" + username + "\", contactid " + contactid);
 | 
			
		||||
      logger.debug("...is_anon " + is_anon + ", email_verified " + email_verified);
 | 
			
		||||
      logger.debug("... level " + level);
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
  } // end loadUserData
 | 
			
		||||
 | 
			
		||||
  private void loadPrefs(Connection conn) throws SQLException, DataException
 | 
			
		||||
  {
 | 
			
		||||
    Statement stmt = conn.createStatement();
 | 
			
		||||
    ResultSet rs = stmt.executeQuery("SELECT * FROM userprefs WHERE uid = " + uid + ";");
 | 
			
		||||
 | 
			
		||||
    if (!(rs.next()))
 | 
			
		||||
      throw new DataException("cannot find preferences for user");
 | 
			
		||||
 | 
			
		||||
    if (my_tz==null)
 | 
			
		||||
      my_tz = TimeZone.getTimeZone(rs.getString("tzid"));
 | 
			
		||||
 | 
			
		||||
    if (my_locale==null)
 | 
			
		||||
      my_locale = LocaleFactory.createLocale(rs.getString("localeid"));
 | 
			
		||||
 | 
			
		||||
  } // end loadPrefs
 | 
			
		||||
 | 
			
		||||
  private void loadPrefs() throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // call through to lower level function
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
      loadPrefs(conn);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // translate into DataException, yadda yadda yadda
 | 
			
		||||
      logger.error("SQL error reading preferences: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("Unable to read user preferences: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end loadPrefs
 | 
			
		||||
 | 
			
		||||
  private void sendEmailConfirmation() throws DataException, EmailException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
@ -180,7 +235,7 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
  public boolean isLoggedIn()
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("isLoggedIn(): uid = " + String.valueOf(uid) + ", is_anon = " + String.valueOf(is_anon));
 | 
			
		||||
      logger.debug("isLoggedIn(): uid = " + uid + ", is_anon = " + is_anon);
 | 
			
		||||
    return ((uid!=-1) && !is_anon);
 | 
			
		||||
 | 
			
		||||
  } // end is_logged_in
 | 
			
		||||
@ -195,7 +250,7 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
  {
 | 
			
		||||
    if (isLoggedIn())
 | 
			
		||||
    { // already authenticated, can't authenticate again
 | 
			
		||||
      logger.error("UserContext already authenticated (with uid " + String.valueOf(uid) + ")");
 | 
			
		||||
      logger.error("UserContext already authenticated (with uid " + uid + ")");
 | 
			
		||||
      throw new InternalStateError("context already authenticated");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
@ -302,7 +357,7 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
  public void confirmEmail(int conf_num) throws AccessError, DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("confirmEmail(): confirming for UID " + String.valueOf(uid));
 | 
			
		||||
      logger.debug("confirmEmail(): confirming for UID " + uid);
 | 
			
		||||
    if ((email_verified) || Capability.exemptFromEmailVerification(level))
 | 
			
		||||
    { // already confirmed
 | 
			
		||||
      if (logger.isDebugEnabled())
 | 
			
		||||
@ -368,7 +423,7 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
  public void resendEmailConfirmation() throws DataException, EmailException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("resendEmailConfirmation(): resending for UID " + String.valueOf(uid));
 | 
			
		||||
      logger.debug("resendEmailConfirmation(): resending for UID " + uid);
 | 
			
		||||
    if ((email_verified) || Capability.exemptFromEmailVerification(level))
 | 
			
		||||
    { // already confirmed, no need to resend
 | 
			
		||||
      if (logger.isDebugEnabled())
 | 
			
		||||
@ -433,6 +488,9 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
 | 
			
		||||
  public ContactInfo getContactInfo() throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("getContactInfo() for UID " + uid);
 | 
			
		||||
 | 
			
		||||
    ContactInfoImpl rc;
 | 
			
		||||
    if (contactid>=0)
 | 
			
		||||
      rc = new ContactInfoImpl(datapool,contactid);
 | 
			
		||||
@ -450,11 +508,14 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
 | 
			
		||||
  public boolean putContactInfo(ContactInfo ci) throws DataException, EmailException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("putContactInfo() for UID " + uid);
 | 
			
		||||
 | 
			
		||||
    boolean email_changed = false;
 | 
			
		||||
    if ((ci.getOwnerUID()!=uid) || (ci.getOwnerSIGID()>=0))
 | 
			
		||||
    { // the contact information is not owned correctly
 | 
			
		||||
      logger.error("ContactInfo ownership wrong (it's " + String.valueOf(ci.getOwnerUID()) + ", "
 | 
			
		||||
		   + String.valueOf(ci.getOwnerSIGID()) + "), should be (" + String.valueOf(uid) + ", -1)");
 | 
			
		||||
      logger.error("ContactInfo ownership wrong (it's " + ci.getOwnerUID() + ", " + ci.getOwnerSIGID()
 | 
			
		||||
		   + "), should be (" + uid + ", -1)");
 | 
			
		||||
      throw new DataException("invalid contact information record");
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
@ -481,7 +542,7 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
      { // contact being established for the first time
 | 
			
		||||
	contactid = ci.getContactID();
 | 
			
		||||
	if (logger.isDebugEnabled())
 | 
			
		||||
	  logger.debug("...established initial contact (" + String.valueOf(contactid) + ") for user");
 | 
			
		||||
	  logger.debug("...established initial contact (" + contactid + ") for user");
 | 
			
		||||
	my_email = ci.getEmail();
 | 
			
		||||
	sendEmailConfirmation();
 | 
			
		||||
	email_changed = true;
 | 
			
		||||
@ -524,8 +585,7 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
 | 
			
		||||
      } // end else if
 | 
			
		||||
 | 
			
		||||
      ar = new AuditRecord(AuditRecord.USER_CONTACT_INFO,uid,remote_addr,
 | 
			
		||||
			   "contactid=" + String.valueOf(contactid));
 | 
			
		||||
      ar = new AuditRecord(AuditRecord.USER_CONTACT_INFO,uid,remote_addr,"contactid=" + contactid);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (ClassCastException cce)
 | 
			
		||||
@ -597,7 +657,7 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
  public UserProfile getProfile(int xuid) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("getProfile(#" + String.valueOf(xuid) + ")...");
 | 
			
		||||
      logger.debug("getProfile(#" + xuid + ")...");
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
@ -893,6 +953,94 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
 | 
			
		||||
  } // end getAdminInterface
 | 
			
		||||
 | 
			
		||||
  public Locale getLocale() throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (my_locale==null)
 | 
			
		||||
      loadPrefs();
 | 
			
		||||
 | 
			
		||||
    return my_locale;
 | 
			
		||||
 | 
			
		||||
  } // end getLocale
 | 
			
		||||
 | 
			
		||||
  public void setLocale(Locale locale) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // retrieve a connection from the data pool
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      // create the update statement
 | 
			
		||||
      StringBuffer sql = new StringBuffer("UPDATE userprefs SET localeid = '");
 | 
			
		||||
      sql.append(SQLUtil.encodeString(locale.toString())).append("' WHERE uid = ").append(uid).append(';');
 | 
			
		||||
 | 
			
		||||
      // execute the statement
 | 
			
		||||
      stmt.executeUpdate(sql.toString());
 | 
			
		||||
 | 
			
		||||
      // replace the locale here
 | 
			
		||||
      my_locale = locale;
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // turn SQLException into data exception
 | 
			
		||||
      logger.error("DB error setting user locale: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to set user locale: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure the connection is released before we go
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end setLocale
 | 
			
		||||
 | 
			
		||||
  public TimeZone getTimeZone() throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (my_tz==null)
 | 
			
		||||
      loadPrefs();
 | 
			
		||||
 | 
			
		||||
    return my_tz;
 | 
			
		||||
 | 
			
		||||
  } // end getTimeZone
 | 
			
		||||
 | 
			
		||||
  public void setTimeZone(TimeZone timezone) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // retrieve a connection from the data pool
 | 
			
		||||
      conn = datapool.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
 | 
			
		||||
      // create the update statement
 | 
			
		||||
      StringBuffer sql = new StringBuffer("UPDATE userprefs SET tzid = '");
 | 
			
		||||
      sql.append(SQLUtil.encodeString(timezone.getID())).append("' WHERE uid = ").append(uid).append(';');
 | 
			
		||||
 | 
			
		||||
      // execute the statement
 | 
			
		||||
      stmt.executeUpdate(sql.toString());
 | 
			
		||||
 | 
			
		||||
      // replace the locale here
 | 
			
		||||
      my_tz = timezone;
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // turn SQLException into data exception
 | 
			
		||||
      logger.error("DB error setting user timezone: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to set user timezone: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure the connection is released before we go
 | 
			
		||||
      if (conn!=null)
 | 
			
		||||
	datapool.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end setTimeZone
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface UserBackend
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
@ -918,6 +1066,8 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
 | 
			
		||||
  public String userDefaultPseud() throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("userDefaultPseud() for UID " + uid);
 | 
			
		||||
    if (my_pseud==null)
 | 
			
		||||
      getContactInfo();
 | 
			
		||||
    return my_pseud;
 | 
			
		||||
@ -999,8 +1149,8 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
		   java.util.Date created, java.util.Date last_access)
 | 
			
		||||
  {
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("loadNewUser() on UserContext: addr " + remote_addr + ", uid " + String.valueOf(uid)
 | 
			
		||||
		   + ", level " + String.valueOf(level) + ", username \"" + username + "\"");
 | 
			
		||||
      logger.debug("loadNewUser() on UserContext: addr " + remote_addr + ", uid " + uid + ", level "
 | 
			
		||||
		   + level + ", username \"" + username + "\"");
 | 
			
		||||
 | 
			
		||||
    this.remote_addr = remote_addr;
 | 
			
		||||
    this.uid = uid;
 | 
			
		||||
 | 
			
		||||
@ -304,6 +304,8 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
 | 
			
		||||
  private int[] gp_ints;                              // global integer parameters
 | 
			
		||||
  private MasterSideBox[] sideboxes;                  // master sidebox table
 | 
			
		||||
  private Hashtable sidebox_ids = new Hashtable();    // maps sidebox IDs to MasterSideBox objects
 | 
			
		||||
  private Vector cache_fp_posts = new Vector();       // all posts that have been published to front page
 | 
			
		||||
  private boolean cache_fp_posts_busy = false;        // busy flag for above vector
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
@ -333,8 +335,8 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
 | 
			
		||||
  private void loadDefaults(Statement stmt) throws SQLException, DataException
 | 
			
		||||
  {
 | 
			
		||||
    final String query =
 | 
			
		||||
        "SELECT posts_per_page, old_posts_at_top, max_search_page, max_sig_mbr_page, max_conf_mbr_page "
 | 
			
		||||
      + "FROM globals;";
 | 
			
		||||
        "SELECT posts_per_page, old_posts_at_top, max_search_page, max_sig_mbr_page, max_conf_mbr_page, "
 | 
			
		||||
      + "fp_posts FROM globals;";
 | 
			
		||||
    ResultSet rs = stmt.executeQuery(query);
 | 
			
		||||
    if (!(rs.next()))
 | 
			
		||||
      throw new DataException("Globals table does not appear to be loaded!");
 | 
			
		||||
@ -345,6 +347,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
 | 
			
		||||
    gp_ints[IP_MAXSEARCHRETURN] = rs.getInt(3);
 | 
			
		||||
    gp_ints[IP_MAXSIGMEMBERDISPLAY] = rs.getInt(4);
 | 
			
		||||
    gp_ints[IP_MAXCONFMEMBERDISPLAY] = rs.getInt(5);
 | 
			
		||||
    gp_ints[IP_NUMFRONTPAGEPOSTS] = rs.getInt(6);
 | 
			
		||||
    
 | 
			
		||||
  } // end loadDefaults
 | 
			
		||||
 | 
			
		||||
@ -489,7 +492,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
    // Allocate the global parameter arrays.
 | 
			
		||||
    gp_ints = new int[5];
 | 
			
		||||
    gp_ints = new int[6];
 | 
			
		||||
 | 
			
		||||
    // initialize anything that requires us to pull from the database
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
@ -1391,6 +1394,48 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
 | 
			
		||||
 | 
			
		||||
  } // end getMasterSideBoxList
 | 
			
		||||
 | 
			
		||||
  public List getPublishedMessages(boolean all) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    Vector rc = new Vector();
 | 
			
		||||
 | 
			
		||||
    synchronized (this)
 | 
			
		||||
    { // Make sure the cache is in condition.
 | 
			
		||||
      while (cache_fp_posts_busy)
 | 
			
		||||
      { // the list is busy, don't fsck with it until we're done
 | 
			
		||||
	try
 | 
			
		||||
	{ // wait to see if they can be un-busy
 | 
			
		||||
	  wait();
 | 
			
		||||
 | 
			
		||||
	} // end try
 | 
			
		||||
	catch (InterruptedException e)
 | 
			
		||||
	{ // do nothing
 | 
			
		||||
	} // end catch
 | 
			
		||||
 | 
			
		||||
      } // end while
 | 
			
		||||
 | 
			
		||||
      // If the cache list contains too few items, backfill it from the database.
 | 
			
		||||
      if (cache_fp_posts.size()<gp_ints[IP_NUMFRONTPAGEPOSTS])
 | 
			
		||||
	PublishedMessageImpl.backfillCache(cache_fp_posts,gp_ints[IP_NUMFRONTPAGEPOSTS],datapool);
 | 
			
		||||
 | 
			
		||||
      // Copy the contents to the return vector, casting them to TopicMessageContext.
 | 
			
		||||
      Iterator it = cache_fp_posts.iterator();
 | 
			
		||||
      while (it.hasNext())
 | 
			
		||||
      { // cast each element and add the casted object to the output
 | 
			
		||||
	PublishedMessageImpl pmi = (PublishedMessageImpl)(it.next());
 | 
			
		||||
	TopicMessageContext ctxt = (TopicMessageContext)pmi;
 | 
			
		||||
	rc.add(ctxt);
 | 
			
		||||
 | 
			
		||||
      } // end while
 | 
			
		||||
 | 
			
		||||
    } // end synchronized block
 | 
			
		||||
 | 
			
		||||
    if (all)  // add the extra postings to the list
 | 
			
		||||
      PublishedMessageImpl.backfillReturn(rc,datapool);
 | 
			
		||||
 | 
			
		||||
    return new ReadOnlyVector(rc);
 | 
			
		||||
 | 
			
		||||
  } // end getPublishedMessages
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface EngineBackend
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
@ -1805,4 +1850,42 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
 | 
			
		||||
 | 
			
		||||
  } // end getMasterSideBoxDescriptor
 | 
			
		||||
 | 
			
		||||
  public synchronized void startPublish()
 | 
			
		||||
  {
 | 
			
		||||
    cache_fp_posts_busy = true;
 | 
			
		||||
 | 
			
		||||
  } // end startPublish
 | 
			
		||||
 | 
			
		||||
  public synchronized void publishNew(PublishedMessageImpl pubmsg)
 | 
			
		||||
  {
 | 
			
		||||
    if (pubmsg!=null)
 | 
			
		||||
    { // add the new message
 | 
			
		||||
      cache_fp_posts.add(0,pubmsg);
 | 
			
		||||
      while (cache_fp_posts.size()>gp_ints[IP_NUMFRONTPAGEPOSTS])
 | 
			
		||||
	cache_fp_posts.remove(cache_fp_posts.size()-1);
 | 
			
		||||
 | 
			
		||||
    } // end pubmsg
 | 
			
		||||
 | 
			
		||||
    cache_fp_posts_busy = false;
 | 
			
		||||
    notifyAll();
 | 
			
		||||
 | 
			
		||||
  } // end publishNew
 | 
			
		||||
 | 
			
		||||
  public synchronized void unpublish(long postid)
 | 
			
		||||
  {
 | 
			
		||||
    Iterator it = cache_fp_posts.iterator();
 | 
			
		||||
    while (it.hasNext())
 | 
			
		||||
    { // get each published message in the cache in turn, looking for the specified post ID
 | 
			
		||||
      PublishedMessageImpl pmi = (PublishedMessageImpl)(it.next());
 | 
			
		||||
      if (pmi.getPostID()==postid)
 | 
			
		||||
      { // drop the specified post ID like a hot rock
 | 
			
		||||
	it.remove();
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
    } // end while
 | 
			
		||||
 | 
			
		||||
  } // end unpublish
 | 
			
		||||
 | 
			
		||||
} // end class VeniceEngineImpl
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * 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 Community System.
 | 
			
		||||
 * 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
 | 
			
		||||
@ -19,7 +19,8 @@ package com.silverwrist.venice.security;
 | 
			
		||||
 | 
			
		||||
public interface Audit
 | 
			
		||||
{
 | 
			
		||||
  // Codes 0-100 - System events
 | 
			
		||||
  // Codes 1-100 - System events
 | 
			
		||||
  public static final int PUBLISH_POST = 1;
 | 
			
		||||
 | 
			
		||||
  // Codes 101-200 - Login/user events
 | 
			
		||||
  public static final int LOGIN_OK = 101;
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * 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 Community System.
 | 
			
		||||
 * 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
 | 
			
		||||
@ -103,4 +103,10 @@ public class Capability implements SecLevels
 | 
			
		||||
 | 
			
		||||
  } // end canAdministerSystem
 | 
			
		||||
 | 
			
		||||
  public static boolean canPublishToFrontPage(int level)
 | 
			
		||||
  {
 | 
			
		||||
    return (level>=GLOBAL_ANYADMIN);
 | 
			
		||||
 | 
			
		||||
  } // end canPublishToFrontPage
 | 
			
		||||
 | 
			
		||||
} // end class Capability
 | 
			
		||||
 | 
			
		||||
@ -172,6 +172,30 @@ public class PostOperations extends VeniceServlet
 | 
			
		||||
 | 
			
		||||
    } // end if ("nuke")
 | 
			
		||||
 | 
			
		||||
    if (cmd.equals("PU"))
 | 
			
		||||
    { // we want to publish the message to the front page
 | 
			
		||||
      try
 | 
			
		||||
      { // attempt to publish the message
 | 
			
		||||
	msg.publish();
 | 
			
		||||
 | 
			
		||||
	// go back and display stuff
 | 
			
		||||
	throw new RedirectResult(location);
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (DataException de)
 | 
			
		||||
      { // there was a database error
 | 
			
		||||
	return new ErrorBox("Database Error","Database error publishing message: " + de.getMessage(),
 | 
			
		||||
			    location);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
      catch (AccessError ae)
 | 
			
		||||
      { // naughty naughty = you can't do this!
 | 
			
		||||
	return new ErrorBox("Access Error",ae.getMessage(),location);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    // unrecognized command!
 | 
			
		||||
    logger.error("invalid command to PostOperations.doGet: " + cmd);
 | 
			
		||||
    return new ErrorBox("Internal Error","Invalid command to PostOperations.doGet",location);
 | 
			
		||||
 | 
			
		||||
@ -76,7 +76,7 @@ public class Top extends VeniceServlet
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // attempt to get the user content
 | 
			
		||||
      return new TopDisplay(getServletContext(),user);
 | 
			
		||||
      return new TopDisplay(getServletContext(),engine,user);
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (DataException de)
 | 
			
		||||
 | 
			
		||||
@ -565,7 +565,7 @@ public abstract class VeniceServlet extends HttpServlet
 | 
			
		||||
    ServletContext ctxt = getServletContext();
 | 
			
		||||
    VeniceEngine engine = Variables.getVeniceEngine(ctxt);
 | 
			
		||||
    UserContext user = Variables.getUserContext(ctxt,request,request.getSession(true));
 | 
			
		||||
    RenderData rdat = RenderConfig.createRenderData(ctxt,request,response);
 | 
			
		||||
    RenderData rdat = RenderConfig.createRenderData(ctxt,user,request,response);
 | 
			
		||||
    ServletMultipartHandler mphandler = null;
 | 
			
		||||
    VeniceContent content = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * 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 Community System.
 | 
			
		||||
 * 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
 | 
			
		||||
@ -25,6 +25,11 @@ import com.silverwrist.venice.core.Country;
 | 
			
		||||
 | 
			
		||||
public class CDCountryListFormField extends CDPickListFormField
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructors
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public CDCountryListFormField(String name, String caption, String caption2, boolean required,
 | 
			
		||||
				List country_list)
 | 
			
		||||
  {
 | 
			
		||||
@ -38,6 +43,11 @@ public class CDCountryListFormField extends CDPickListFormField
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Overrides from class CDPickListFormField
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  protected void renderChoice(Writer out, RenderData rdat, Object obj, String my_value) throws IOException
 | 
			
		||||
  {
 | 
			
		||||
    Country c = (Country)obj;
 | 
			
		||||
@ -48,6 +58,11 @@ public class CDCountryListFormField extends CDPickListFormField
 | 
			
		||||
 | 
			
		||||
  } // end renderChoice
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface CDFormField
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public CDFormField duplicate()
 | 
			
		||||
  {
 | 
			
		||||
    return new CDCountryListFormField(this);
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,106 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 java.io.Writer;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
 | 
			
		||||
public class CDLocaleListFormField extends CDPickListFormField
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Private list implementation
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  static class LocaleList extends AbstractList
 | 
			
		||||
  {
 | 
			
		||||
    private Locale[] array;  // local array
 | 
			
		||||
 | 
			
		||||
    LocaleList()
 | 
			
		||||
    {
 | 
			
		||||
      array = Locale.getAvailableLocales();
 | 
			
		||||
 | 
			
		||||
    } // end constructor
 | 
			
		||||
 | 
			
		||||
    protected void finalize() throws Throwable
 | 
			
		||||
    {
 | 
			
		||||
      array = null;
 | 
			
		||||
      super.finalize();
 | 
			
		||||
 | 
			
		||||
    } // end finalize
 | 
			
		||||
 | 
			
		||||
    public Object get(int index)
 | 
			
		||||
    {
 | 
			
		||||
      return array[index];
 | 
			
		||||
 | 
			
		||||
    } // end get
 | 
			
		||||
 | 
			
		||||
    public int size()
 | 
			
		||||
    {
 | 
			
		||||
      return array.length;
 | 
			
		||||
      
 | 
			
		||||
    } // end size
 | 
			
		||||
 | 
			
		||||
  } // end class LocaleList
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructors
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public CDLocaleListFormField(String name, String caption, String caption2, boolean required)
 | 
			
		||||
  {
 | 
			
		||||
    super(name,caption,caption2,required,new LocaleList());
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  protected CDLocaleListFormField(CDLocaleListFormField other)
 | 
			
		||||
  {
 | 
			
		||||
    super(other);
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Overrides from class CDPickListFormField
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  protected void renderChoice(Writer out, RenderData rdat, Object obj, String my_value) throws IOException
 | 
			
		||||
  {
 | 
			
		||||
    Locale l = (Locale)obj;
 | 
			
		||||
    out.write("<OPTION VALUE=\"" + l.toString() + "\"");
 | 
			
		||||
    if (l.toString().equals(my_value))
 | 
			
		||||
      out.write(" SELECTED");
 | 
			
		||||
    out.write(">" + StringUtil.encodeHTML(l.getDisplayName()) + "</OPTION>\n");
 | 
			
		||||
 | 
			
		||||
  } // end renderChoice
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface CDFormField
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public CDFormField duplicate()
 | 
			
		||||
  {
 | 
			
		||||
    return new CDLocaleListFormField(this);
 | 
			
		||||
 | 
			
		||||
  } // end duplicate
 | 
			
		||||
 | 
			
		||||
} // end class CDLocaleListFormField
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * 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 Community System.
 | 
			
		||||
 * 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
 | 
			
		||||
@ -25,8 +25,18 @@ import com.silverwrist.util.StringUtil;
 | 
			
		||||
 | 
			
		||||
public abstract class CDPickListFormField extends CDBaseFormField
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Attributes
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private List choices;
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructors
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  protected CDPickListFormField(String name, String caption, String caption2, boolean required,
 | 
			
		||||
				List choices)
 | 
			
		||||
  {
 | 
			
		||||
@ -42,9 +52,19 @@ public abstract class CDPickListFormField extends CDBaseFormField
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Abstract method declarations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  protected abstract void renderChoice(Writer out, RenderData rdat, Object obj, String my_value)
 | 
			
		||||
      throws IOException;
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Overrides from class CDBaseFormField
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  protected void renderActualField(Writer out, RenderData rdat) throws IOException
 | 
			
		||||
  {
 | 
			
		||||
    out.write("<SELECT NAME=\"" + getName() + "\" SIZE=1");
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,106 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 java.io.Writer;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
 | 
			
		||||
public class CDTimeZoneListFormField extends CDPickListFormField
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Private list implementation
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  static class TimeZoneList extends AbstractList
 | 
			
		||||
  {
 | 
			
		||||
    private String[] array;  // local array
 | 
			
		||||
 | 
			
		||||
    TimeZoneList()
 | 
			
		||||
    {
 | 
			
		||||
      array = TimeZone.getAvailableIDs();
 | 
			
		||||
 | 
			
		||||
    } // end constructor
 | 
			
		||||
 | 
			
		||||
    protected void finalize() throws Throwable
 | 
			
		||||
    {
 | 
			
		||||
      array = null;
 | 
			
		||||
      super.finalize();
 | 
			
		||||
 | 
			
		||||
    } // end finalize
 | 
			
		||||
 | 
			
		||||
    public Object get(int index)
 | 
			
		||||
    {
 | 
			
		||||
      return array[index];
 | 
			
		||||
 | 
			
		||||
    } // end get
 | 
			
		||||
 | 
			
		||||
    public int size()
 | 
			
		||||
    {
 | 
			
		||||
      return array.length;
 | 
			
		||||
      
 | 
			
		||||
    } // end size
 | 
			
		||||
 | 
			
		||||
  } // end class TimeZoneList
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructors
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public CDTimeZoneListFormField(String name, String caption, String caption2, boolean required)
 | 
			
		||||
  {
 | 
			
		||||
    super(name,caption,caption2,required,new TimeZoneList());
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  protected CDTimeZoneListFormField(CDTimeZoneListFormField other)
 | 
			
		||||
  {
 | 
			
		||||
    super(other);
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Overrides from class CDPickListFormField
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  protected void renderChoice(Writer out, RenderData rdat, Object obj, String my_value) throws IOException
 | 
			
		||||
  {
 | 
			
		||||
    String id = (String)obj;
 | 
			
		||||
    out.write("<OPTION VALUE=\"" + id + "\"");
 | 
			
		||||
    if (id.equals(my_value))
 | 
			
		||||
      out.write(" SELECTED");
 | 
			
		||||
    out.write(">" + StringUtil.encodeHTML(id) + "</OPTION>\n");
 | 
			
		||||
 | 
			
		||||
  } // end renderChoice
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Implementations from interface CDFormField
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public CDFormField duplicate()
 | 
			
		||||
  {
 | 
			
		||||
    return new CDTimeZoneListFormField(this);
 | 
			
		||||
 | 
			
		||||
  } // end duplicate
 | 
			
		||||
 | 
			
		||||
} // end class CDTimeZoneListFormField
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * 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 Community System.
 | 
			
		||||
 * 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
 | 
			
		||||
@ -17,13 +17,19 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.silverwrist.venice.servlets.format;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import com.silverwrist.util.LocaleFactory;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.ValidationException;
 | 
			
		||||
import com.silverwrist.venice.core.*;
 | 
			
		||||
 | 
			
		||||
public class EditProfileDialog extends ContentDialog
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructors
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public EditProfileDialog(List country_list)
 | 
			
		||||
  {
 | 
			
		||||
    super("Edit Your Profile",null,"profform","account");
 | 
			
		||||
@ -62,6 +68,9 @@ public class EditProfileDialog extends ContentDialog
 | 
			
		||||
    addFormField(new CDFormCategoryHeader("Personal"));
 | 
			
		||||
    addFormField(new CDTextFormField("descr","Personal description",null,false,32,255));
 | 
			
		||||
    // TODO: add photo selection/uploading method here
 | 
			
		||||
    addFormField(new CDFormCategoryHeader("User Preferences"));
 | 
			
		||||
    addFormField(new CDLocaleListFormField("locale","Default locale","(for formatting dates/times)",true));
 | 
			
		||||
    addFormField(new CDTimeZoneListFormField("tz","Default time zone",null,true));
 | 
			
		||||
    addCommandButton(new CDImageButton("update","bn_update.gif","Update",80,24));
 | 
			
		||||
    addCommandButton(new CDImageButton("cancel","bn_cancel.gif","Cancel",80,24));
 | 
			
		||||
 | 
			
		||||
@ -73,6 +82,22 @@ public class EditProfileDialog extends ContentDialog
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Overrides from class Object
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public Object clone()
 | 
			
		||||
  {
 | 
			
		||||
    return new EditProfileDialog(this);
 | 
			
		||||
 | 
			
		||||
  } // end clone
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Overrides from class ContentDialog
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  protected void validateWholeForm() throws ValidationException
 | 
			
		||||
  {
 | 
			
		||||
    String pass1 = getFieldValue("pass1");
 | 
			
		||||
@ -93,6 +118,11 @@ public class EditProfileDialog extends ContentDialog
 | 
			
		||||
 | 
			
		||||
  } // end validateWholeForm
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public void setTarget(String target)
 | 
			
		||||
  {
 | 
			
		||||
    setHiddenField("tgt",target);
 | 
			
		||||
@ -132,6 +162,8 @@ public class EditProfileDialog extends ContentDialog
 | 
			
		||||
      setFieldValue("pvt_email","Y");
 | 
			
		||||
    setFieldValue("url",ci.getURL());
 | 
			
		||||
    setFieldValue("descr",uc.getDescription());
 | 
			
		||||
    setFieldValue("locale",uc.getLocale().toString());
 | 
			
		||||
    setFieldValue("tz",uc.getTimeZone().getID());
 | 
			
		||||
 | 
			
		||||
  } // end setupDialog
 | 
			
		||||
 | 
			
		||||
@ -172,8 +204,10 @@ public class EditProfileDialog extends ContentDialog
 | 
			
		||||
    // Store the completed contact info.
 | 
			
		||||
    boolean retval = uc.putContactInfo(ci);
 | 
			
		||||
 | 
			
		||||
    // Save off the user's description.
 | 
			
		||||
    // Save off the user's description and preferences.
 | 
			
		||||
    uc.setDescription(getFieldValue("descr"));
 | 
			
		||||
    uc.setLocale(LocaleFactory.createLocale(getFieldValue("locale")));
 | 
			
		||||
    uc.setTimeZone(TimeZone.getTimeZone(getFieldValue("tz")));
 | 
			
		||||
 | 
			
		||||
    // Finally, change the password if applicable.
 | 
			
		||||
    foo = getFieldValue("pass1");
 | 
			
		||||
@ -192,10 +226,4 @@ public class EditProfileDialog extends ContentDialog
 | 
			
		||||
 | 
			
		||||
  } // end resetOnError
 | 
			
		||||
 | 
			
		||||
  public Object clone()
 | 
			
		||||
  {
 | 
			
		||||
    return new EditProfileDialog(this);
 | 
			
		||||
 | 
			
		||||
  } // end clone
 | 
			
		||||
 | 
			
		||||
} // end class EditProfileDialog
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
 * 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 Community System.
 | 
			
		||||
 * 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
 | 
			
		||||
@ -29,6 +29,8 @@ import org.xml.sax.SAXParseException;
 | 
			
		||||
import com.silverwrist.util.DOMElementHelper;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.core.ConfigException;
 | 
			
		||||
import com.silverwrist.venice.core.UserContext;
 | 
			
		||||
import com.silverwrist.venice.servlets.Variables;
 | 
			
		||||
 | 
			
		||||
public class RenderConfig
 | 
			
		||||
{
 | 
			
		||||
@ -56,6 +58,7 @@ public class RenderConfig
 | 
			
		||||
  private String image_url;
 | 
			
		||||
  private String static_url;
 | 
			
		||||
  private String site_logo;
 | 
			
		||||
  private Hashtable stock_messages;
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
@ -171,6 +174,35 @@ public class RenderConfig
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("Site logo: " + image_url);
 | 
			
		||||
 | 
			
		||||
    Element msg_sect = root_h.getSubElement("messages");
 | 
			
		||||
    if (msg_sect==null)
 | 
			
		||||
    { // no <messages/> section - bail out now!
 | 
			
		||||
      logger.fatal("config document has no <messages/> section");
 | 
			
		||||
      throw new ConfigException("no <messages/> section found in config file",root);
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
    // Initialize the stock messages list.
 | 
			
		||||
    stock_messages = new Hashtable();
 | 
			
		||||
    NodeList msg_nodes = msg_sect.getChildNodes();
 | 
			
		||||
    for (int i=0; i<msg_nodes.getLength(); i++)
 | 
			
		||||
    { // examine all subnodes to add them to the message text
 | 
			
		||||
      Node msgn = msg_nodes.item(i);
 | 
			
		||||
      if (msgn.getNodeType()==Node.ELEMENT_NODE)
 | 
			
		||||
      { // add it to the hash table by its tag name
 | 
			
		||||
	Element msgel = (Element)msgn;
 | 
			
		||||
	DOMElementHelper h = new DOMElementHelper(msgel);
 | 
			
		||||
	String txt = h.getElementText();
 | 
			
		||||
	if (txt!=null)
 | 
			
		||||
	  stock_messages.put(msgel.getTagName(),txt.trim());
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
    } // end for
 | 
			
		||||
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug(stock_messages.size() + " stock messages loaded from config");
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
@ -335,6 +367,19 @@ public class RenderConfig
 | 
			
		||||
 | 
			
		||||
  } // end writeContentHeader
 | 
			
		||||
 | 
			
		||||
  String getStockMessage(String identifier)
 | 
			
		||||
  {
 | 
			
		||||
    return (String)(stock_messages.get(identifier));
 | 
			
		||||
 | 
			
		||||
  } // end getStockMessage
 | 
			
		||||
 | 
			
		||||
  void writeStockMessage(Writer out, String identifier) throws IOException
 | 
			
		||||
  {
 | 
			
		||||
    String text = (String)(stock_messages.get(identifier));
 | 
			
		||||
    out.write(StringUtil.encodeHTML(text));
 | 
			
		||||
 | 
			
		||||
  } // end writeStockMessage
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Static operations for use by VeniceServlet
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
@ -370,7 +415,15 @@ public class RenderConfig
 | 
			
		||||
  public static RenderData createRenderData(ServletContext ctxt, HttpServletRequest request,
 | 
			
		||||
					    HttpServletResponse response) throws ServletException
 | 
			
		||||
  {
 | 
			
		||||
    return new RenderData(getRenderConfig(ctxt),request,response);
 | 
			
		||||
    UserContext uc = Variables.getUserContext(ctxt,request,request.getSession(true));
 | 
			
		||||
    return new RenderData(getRenderConfig(ctxt),uc,request,response);
 | 
			
		||||
 | 
			
		||||
  } // end createRenderData
 | 
			
		||||
 | 
			
		||||
  public static RenderData createRenderData(ServletContext ctxt, UserContext uc, HttpServletRequest request,
 | 
			
		||||
					    HttpServletResponse response) throws ServletException
 | 
			
		||||
  {
 | 
			
		||||
    return new RenderData(getRenderConfig(ctxt),uc,request,response);
 | 
			
		||||
 | 
			
		||||
  } // end createRenderData
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,9 @@ import javax.servlet.*;
 | 
			
		||||
import javax.servlet.http.*;
 | 
			
		||||
import org.apache.log4j.*;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.core.DataException;
 | 
			
		||||
import com.silverwrist.venice.core.IDUtils;
 | 
			
		||||
import com.silverwrist.venice.core.UserContext;
 | 
			
		||||
import com.silverwrist.venice.db.PostLinkRewriter;
 | 
			
		||||
import com.silverwrist.venice.db.UserNameRewriter;
 | 
			
		||||
 | 
			
		||||
@ -56,7 +58,7 @@ public class RenderData
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  RenderData(RenderConfig rconf, HttpServletRequest request, HttpServletResponse response)
 | 
			
		||||
  RenderData(RenderConfig rconf, UserContext uc, HttpServletRequest request, HttpServletResponse response)
 | 
			
		||||
  {
 | 
			
		||||
    this.rconf = rconf;
 | 
			
		||||
    this.request = request;
 | 
			
		||||
@ -67,9 +69,29 @@ public class RenderData
 | 
			
		||||
    if ((encodings!=null) && (encodings.indexOf("gzip")>=0))
 | 
			
		||||
      can_gzip = true;
 | 
			
		||||
 | 
			
		||||
    // TODO: replace with reading user's preferences
 | 
			
		||||
    my_locale = Locale.getDefault();
 | 
			
		||||
    my_timezone = TimeZone.getDefault();
 | 
			
		||||
    // read the user's preferred locale
 | 
			
		||||
    try
 | 
			
		||||
    { // get the user default locale
 | 
			
		||||
      my_locale = uc.getLocale();
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (DataException de)
 | 
			
		||||
    { // locale problems...
 | 
			
		||||
      my_locale = Locale.getDefault();
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
    // read the user's preferred time zone
 | 
			
		||||
    try
 | 
			
		||||
    { // get the user default timezone
 | 
			
		||||
      my_timezone = uc.getTimeZone();
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (DataException de)
 | 
			
		||||
    { // time zone problems...
 | 
			
		||||
      my_timezone = TimeZone.getDefault();
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
@ -206,6 +228,18 @@ public class RenderData
 | 
			
		||||
 | 
			
		||||
  } // end writeContentSelectorHeader
 | 
			
		||||
 | 
			
		||||
  public String getStockMessage(String identifier)
 | 
			
		||||
  {
 | 
			
		||||
    return rconf.getStockMessage(identifier);
 | 
			
		||||
 | 
			
		||||
  } // end getStockMessage
 | 
			
		||||
 | 
			
		||||
  public void writeStockMessage(Writer out, String identifier) throws IOException
 | 
			
		||||
  {
 | 
			
		||||
    rconf.writeStockMessage(out,identifier);
 | 
			
		||||
 | 
			
		||||
  } // end writeStockMessage
 | 
			
		||||
 | 
			
		||||
  public String formatDateForDisplay(Date date)
 | 
			
		||||
  {
 | 
			
		||||
    DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM,my_locale);
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,9 @@ public class TopDisplay implements ContentRender
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private ServletContext ctxt;
 | 
			
		||||
  private VeniceEngine engine;
 | 
			
		||||
  private UserContext uc;
 | 
			
		||||
  private List top_posts;
 | 
			
		||||
  private List descrs;
 | 
			
		||||
  private VeniceContent[] sideboxes;
 | 
			
		||||
 | 
			
		||||
@ -49,11 +51,14 @@ public class TopDisplay implements ContentRender
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public TopDisplay(ServletContext ctxt, UserContext uc) throws DataException, AccessError, ErrorBox
 | 
			
		||||
  public TopDisplay(ServletContext ctxt, VeniceEngine engine, UserContext uc)
 | 
			
		||||
      throws DataException, AccessError, ErrorBox
 | 
			
		||||
  {
 | 
			
		||||
    // Stash some basic information.
 | 
			
		||||
    this.ctxt = ctxt;
 | 
			
		||||
    this.engine = engine;
 | 
			
		||||
    this.uc = uc;
 | 
			
		||||
    this.top_posts = engine.getPublishedMessages(false);
 | 
			
		||||
    this.descrs = uc.getSideBoxList();
 | 
			
		||||
 | 
			
		||||
    // Create the arrays used to construct sideboxes.
 | 
			
		||||
@ -242,4 +247,57 @@ public class TopDisplay implements ContentRender
 | 
			
		||||
 | 
			
		||||
  } // end renderHere
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public static String getPosterName(TopicMessageContext msg)
 | 
			
		||||
  {
 | 
			
		||||
    try
 | 
			
		||||
    { // have to guard agains a DataException here
 | 
			
		||||
      return msg.getCreatorName();
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (DataException de)
 | 
			
		||||
    { // just return "unknown" on failure
 | 
			
		||||
      return "(unknown)";
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
  } // end getPosterName
 | 
			
		||||
 | 
			
		||||
  public static String getMessageBodyText(TopicMessageContext msg)
 | 
			
		||||
  {
 | 
			
		||||
    try
 | 
			
		||||
    { // have to guard against a DataException here
 | 
			
		||||
      return msg.getBodyText();
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (DataException de)
 | 
			
		||||
    { // just return an error message
 | 
			
		||||
      return "<EM>(Unable to retrieve message data: " + StringUtil.encodeHTML(de.getMessage()) + ")</EM>";
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
 | 
			
		||||
  } // end getMessageBodyText
 | 
			
		||||
 | 
			
		||||
  public int getNumTopPosts()
 | 
			
		||||
  {
 | 
			
		||||
    return top_posts.size();
 | 
			
		||||
 | 
			
		||||
  } // end getNumTopPosts
 | 
			
		||||
 | 
			
		||||
  public TopicMessageContext getTopPost(int index)
 | 
			
		||||
  {
 | 
			
		||||
    return (TopicMessageContext)(top_posts.get(index));
 | 
			
		||||
 | 
			
		||||
  } // end getTopPost
 | 
			
		||||
 | 
			
		||||
  public boolean displayWelcome()
 | 
			
		||||
  {
 | 
			
		||||
    return !(uc.isLoggedIn());
 | 
			
		||||
 | 
			
		||||
  } // end displayWelcome
 | 
			
		||||
 | 
			
		||||
} // end class TopDisplay
 | 
			
		||||
 | 
			
		||||
@ -220,6 +220,11 @@
 | 
			
		||||
         SRC="<%= rdat.getFullImagePath("bn_nuke.gif") %>" ALT="Nuke" WIDTH=80 HEIGHT=24
 | 
			
		||||
         BORDER=0></A><P>
 | 
			
		||||
      <% } // end if (can nuke) %> 
 | 
			
		||||
      <% if (msg.canPublish()) { %>
 | 
			
		||||
        <A HREF="<%= rdat.getEncodedServletPath("postops?" + po_loc + "&cmd=PU") %>"><IMG
 | 
			
		||||
         SRC="<%= rdat.getFullImagePath("bn_publish.gif") %>" ALT="Publish" WIDTH=80 HEIGHT=24
 | 
			
		||||
         BORDER=0></A><P>
 | 
			
		||||
      <% } // end if (can publish) %>
 | 
			
		||||
    </TD></TR></TABLE><BR>
 | 
			
		||||
  <% } // end if (showing advanced controls) %>
 | 
			
		||||
  <% can_line = true; %>
 | 
			
		||||
 | 
			
		||||
@ -26,5 +26,29 @@
 | 
			
		||||
  RenderData rdat = RenderConfig.createRenderData(application,request,response);
 | 
			
		||||
%>
 | 
			
		||||
<% if (rdat.useHTMLComments()) { %><!-- Top content panel --><% } %>
 | 
			
		||||
<% rdat.writeContentHeader(out,"Venice Currents",null); %>
 | 
			
		||||
TODO: Something profound goes here. :-)
 | 
			
		||||
<% if (data.displayWelcome()) { %>
 | 
			
		||||
  <% rdat.writeContentHeader(out,rdat.getStockMessage("welcome-top"),null); %>
 | 
			
		||||
  <%= rdat.getStdFontTag(null,1) %><% rdat.writeStockMessage(out,"welcome"); %></FONT><P>
 | 
			
		||||
<% } // end if %>
 | 
			
		||||
<% rdat.writeContentHeader(out,rdat.getStockMessage("currents-top"),null); %>
 | 
			
		||||
<% int ntp = data.getNumTopPosts(); %>
 | 
			
		||||
<% if (ntp>0) { %>
 | 
			
		||||
  <% for (int i=0; i<ntp; i++) { %>
 | 
			
		||||
    <% if (i>0) { %><HR WIDTH="70%"><% } %>
 | 
			
		||||
    <%
 | 
			
		||||
      TopicMessageContext msg = data.getTopPost(i);
 | 
			
		||||
      String poster = data.getPosterName(msg);
 | 
			
		||||
    %>
 | 
			
		||||
    <%= rdat.getStdFontTag(null,1) %>
 | 
			
		||||
      <B><%= msg.getPseud() %></B>
 | 
			
		||||
      (<EM>
 | 
			
		||||
        <A HREF="<%= rdat.getEncodedServletPath("user/" + poster) %>" TARGET="_blank"><%= poster %></A>,
 | 
			
		||||
        <%= rdat.formatDateForDisplay(msg.getPostDate()) %>
 | 
			
		||||
      </EM>)
 | 
			
		||||
      <P>
 | 
			
		||||
      <PRE><%= rdat.rewritePostData(data.getMessageBodyText(msg)) %></PRE>
 | 
			
		||||
    </FONT>
 | 
			
		||||
  <% } // end for %>
 | 
			
		||||
<% } else { %>
 | 
			
		||||
  <%= rdat.getStdFontTag(null,1) %><EM>No front page postings found.</EM></FONT>
 | 
			
		||||
<% } // end if %>
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								web/images/bn_publish.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								web/images/bn_publish.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 937 B  | 
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user