* landed support for reading topics and posting followup messages to a topic -
the basis of the conferencing engine is now firmly in place * tweaks to the HTML Checker to make it better at breaking lines without leaving stranded punctuation at the beginning or end of a line * also modified dictionary to better handle possessives and hyphenates * as always, miscellaneous tweaks and bugfizes as I spot them
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 4.6 KiB |
|
@ -51,7 +51,7 @@
|
|||
<LI>Output uses XML and gets formatted into [X]HTML via XSLT; "themeable"/"skinnable" interface</LI>
|
||||
<LI>Conferencing/other functionality available via XML-RPC or SOAP calls</LI>
|
||||
<LI>News page creation (see Slash, Squishdot, Scoop)</LI>
|
||||
<LI>Member trust metrics (see Slashdot "karma," Scoop "mojo," Advogato distributed trust metric)</LI>
|
||||
<LI>Member trust metrics (see Slashdot "karma," Scoop "mojo," Advogato distributed trust metric) <B><EM>(Feature indefinitely shelved at the request of the EMinds community)</EM></B></LI>
|
||||
<LI>User diary pages (see Advogato, Kuro5hin)</LI>
|
||||
<LI>Moderated discussions (see Slash, Scoop)</LI>
|
||||
<LI>Collaborative database facility (see Wiki, Everything2)</LI>
|
||||
|
|
|
@ -1,8 +1,105 @@
|
|||
advogato
|
||||
ain't
|
||||
anla'shok
|
||||
bajor
|
||||
bios
|
||||
boitano
|
||||
boromax
|
||||
can't
|
||||
cartman
|
||||
checkouts
|
||||
couldn't
|
||||
crewmember
|
||||
crewmembers
|
||||
deflector
|
||||
deflectors
|
||||
delenn
|
||||
didn't
|
||||
dilithium
|
||||
docking
|
||||
doesn't
|
||||
don't
|
||||
eminds
|
||||
entil'zha
|
||||
eps
|
||||
erbo
|
||||
fett
|
||||
followup
|
||||
franklin
|
||||
fucking
|
||||
hairstyle
|
||||
hairstyles
|
||||
hasn't
|
||||
he'd
|
||||
html
|
||||
i'd
|
||||
i'll
|
||||
i'm
|
||||
i've
|
||||
inducers
|
||||
it'd
|
||||
khan
|
||||
kubla
|
||||
kyle
|
||||
lafou
|
||||
ma'am
|
||||
maddog
|
||||
marillion
|
||||
minbar
|
||||
minbari
|
||||
mr
|
||||
mustn't
|
||||
nacelle
|
||||
nacelles
|
||||
navigational
|
||||
ops
|
||||
padd
|
||||
peachy
|
||||
planitia
|
||||
planum
|
||||
psi
|
||||
refit
|
||||
refitting
|
||||
replicator
|
||||
repost
|
||||
reposted
|
||||
rom
|
||||
runabout
|
||||
salchow
|
||||
salchows
|
||||
sarcastically
|
||||
silverwrist
|
||||
snarf
|
||||
snarfage
|
||||
snazzy
|
||||
sourceforge
|
||||
spaceport
|
||||
spellchecker
|
||||
spellchucker
|
||||
spelunker
|
||||
spelunkers
|
||||
st
|
||||
starbase
|
||||
starfleet
|
||||
starship
|
||||
straightening
|
||||
stunted
|
||||
terrence
|
||||
they're
|
||||
turbolift
|
||||
tuzanor
|
||||
umbilical
|
||||
umbilicals
|
||||
url
|
||||
utne
|
||||
valen
|
||||
veni
|
||||
we'll
|
||||
we're
|
||||
webb
|
||||
webbme
|
||||
won't
|
||||
wouldn't
|
||||
you'd
|
||||
you'll
|
||||
you're
|
||||
|
|
13
etc/web.xml
|
@ -142,6 +142,14 @@
|
|||
<servlet-class>com.silverwrist.venice.servlets.ConfDisplay</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>postmessage</servlet-name>
|
||||
<description>
|
||||
Posting messages to a conference.
|
||||
</description>
|
||||
<servlet-class>com.silverwrist.venice.servlets.PostMessage</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<!-- the following are test servlets, they should go away -->
|
||||
|
||||
<servlet>
|
||||
|
@ -200,6 +208,11 @@
|
|||
<url-pattern>/confdisp</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>postmessage</servlet-name>
|
||||
<url-pattern>/post</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- the following are test servlets, they should go away -->
|
||||
<servlet-mapping>
|
||||
<servlet-name>testformdata</servlet-name>
|
||||
|
|
|
@ -416,6 +416,10 @@ INSERT INTO refaudit (type, descr) VALUES
|
|||
(307, 'Delete Topic'),
|
||||
(308, 'Set Topic Frozen'),
|
||||
(309, 'Set Topic Archive'),
|
||||
(310, 'Post Message'),
|
||||
(311, 'Hide Message'),
|
||||
(312, 'Scribble Message'),
|
||||
(313, 'Nuke Message'),
|
||||
(9999999, 'DUMMY');
|
||||
|
||||
# The ISO 3166 two-letter country codes. Source is
|
||||
|
|
|
@ -64,4 +64,9 @@ public interface TopicContext
|
|||
|
||||
public abstract void fixSeen() throws DataException;
|
||||
|
||||
public abstract List getMessages(int low, int high) throws DataException, AccessError;
|
||||
|
||||
public abstract TopicMessageContext postNewMessage(long parent, String pseud, String text)
|
||||
throws DataException, AccessError;
|
||||
|
||||
} // end interface TopicContext
|
||||
|
|
64
src/com/silverwrist/venice/core/TopicMessageContext.java
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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 Community 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;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public interface TopicMessageContext
|
||||
{
|
||||
public abstract long getPostID();
|
||||
|
||||
public abstract long getParentPostID();
|
||||
|
||||
public abstract int getPostNumber();
|
||||
|
||||
public abstract int getNumLines();
|
||||
|
||||
public abstract int getCreatorUID();
|
||||
|
||||
public abstract String getCreatorName() throws DataException;
|
||||
|
||||
public abstract Date getPostDate();
|
||||
|
||||
public abstract boolean isHidden();
|
||||
|
||||
public abstract boolean isScribbled();
|
||||
|
||||
public abstract boolean isNuked();
|
||||
|
||||
public abstract Date getScribbleDate();
|
||||
|
||||
public abstract String getPseud();
|
||||
|
||||
public abstract String getBodyText() throws DataException;
|
||||
|
||||
public abstract boolean hasAttachment();
|
||||
|
||||
public abstract boolean canHide();
|
||||
|
||||
public abstract boolean canScribble();
|
||||
|
||||
public abstract boolean canNuke();
|
||||
|
||||
public abstract void setHidden(boolean flag) throws DataException, AccessError;
|
||||
|
||||
public abstract void scribble() throws DataException, AccessError;
|
||||
|
||||
public abstract void nuke() throws DataException, AccessError;
|
||||
|
||||
} // end interface TopicMessageContext
|
|
@ -17,8 +17,10 @@
|
|||
*/
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.sql.*;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import com.silverwrist.venice.core.DataException;
|
||||
|
||||
public interface ConferenceBackend extends SIGBackend
|
||||
{
|
||||
|
@ -32,4 +34,14 @@ public interface ConferenceBackend extends SIGBackend
|
|||
|
||||
public abstract String realConfAlias();
|
||||
|
||||
public abstract boolean userCanScribble();
|
||||
|
||||
public abstract boolean userCanNuke();
|
||||
|
||||
public abstract boolean userCanRead();
|
||||
|
||||
public abstract boolean userCanPost();
|
||||
|
||||
public abstract void touchUpdate(Connection conn, java.util.Date date) throws DataException;
|
||||
|
||||
} // end interface ConferenceBackend
|
||||
|
|
|
@ -932,6 +932,37 @@ class ConferenceCoreData implements ConferenceData
|
|||
|
||||
} // end createNewTopic
|
||||
|
||||
public boolean canScribblePosts(int level)
|
||||
{
|
||||
return (level>=nuke_level);
|
||||
|
||||
} // end canScribblePosts
|
||||
|
||||
public boolean canNukePosts(int level)
|
||||
{
|
||||
return (level>=nuke_level);
|
||||
|
||||
} // end canNukePosts
|
||||
|
||||
public synchronized void touchUpdate(Connection conn, java.util.Date date) throws DataException
|
||||
{
|
||||
try
|
||||
{ // update the last update date
|
||||
Statement stmt = conn.createStatement();
|
||||
StringBuffer sql = new StringBuffer("UPDATE confs SET lastupdate = '");
|
||||
sql.append(SQLUtil.encodeDate(date)).append("' WHERE confid = ").append(confid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
last_update = date;
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // convert the SQLException
|
||||
throw new DataException("Database error updating conference: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end touchUpdate
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static operations (usable only from within package)
|
||||
*--------------------------------------------------------------------------------
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.silverwrist.venice.core.DataException;
|
||||
|
@ -79,4 +80,10 @@ public interface ConferenceData extends ReferencedData
|
|||
public abstract ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
|
||||
int body_lines) throws DataException;
|
||||
|
||||
public abstract boolean canScribblePosts(int level);
|
||||
|
||||
public abstract boolean canNukePosts(int level);
|
||||
|
||||
public abstract void touchUpdate(Connection conn, Date date) throws DataException;
|
||||
|
||||
} // end interface ConferenceData
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
package com.silverwrist.venice.core.impl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.silverwrist.venice.core.DataException;
|
||||
|
@ -91,4 +92,10 @@ public interface ConferenceSIGContext extends ReferencedData
|
|||
public abstract ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
|
||||
int body_lines) throws DataException;
|
||||
|
||||
public abstract boolean canScribblePosts(int level);
|
||||
|
||||
public abstract boolean canNukePosts(int level);
|
||||
|
||||
public abstract void touchUpdate(Connection conn, Date date) throws DataException;
|
||||
|
||||
} // end interface ConferenceSIGContext
|
||||
|
|
|
@ -618,4 +618,34 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
|
|||
|
||||
} // end createNewTopic
|
||||
|
||||
public boolean canScribblePosts(int level)
|
||||
{
|
||||
ConferenceData c = getConferenceDataNE();
|
||||
if (c==null)
|
||||
return false;
|
||||
if (level<this.level)
|
||||
return c.canScribblePosts(this.level);
|
||||
else
|
||||
return c.canScribblePosts(level);
|
||||
|
||||
} // end canScribblePosts
|
||||
|
||||
public boolean canNukePosts(int level)
|
||||
{
|
||||
ConferenceData c = getConferenceDataNE();
|
||||
if (c==null)
|
||||
return false;
|
||||
if (level<this.level)
|
||||
return c.canNukePosts(this.level);
|
||||
else
|
||||
return c.canNukePosts(level);
|
||||
|
||||
} // end canNukePosts
|
||||
|
||||
public void touchUpdate(Connection conn, java.util.Date date) throws DataException
|
||||
{
|
||||
getConferenceData().touchUpdate(conn,date);
|
||||
|
||||
} // end touchUpdate
|
||||
|
||||
} // end class ConferenceSIGContextImpl
|
||||
|
|
|
@ -1047,6 +1047,42 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
|||
|
||||
} // end realConfAlias
|
||||
|
||||
public boolean userCanScribble()
|
||||
{
|
||||
ConferenceSIGContext c = getConferenceDataNE();
|
||||
if (c==null)
|
||||
return false;
|
||||
return c.canScribblePosts(level);
|
||||
|
||||
} // end userCanScribble
|
||||
|
||||
public boolean userCanNuke()
|
||||
{
|
||||
ConferenceSIGContext c = getConferenceDataNE();
|
||||
if (c==null)
|
||||
return false;
|
||||
return c.canNukePosts(level);
|
||||
|
||||
} // end userCanNuke
|
||||
|
||||
public boolean userCanRead()
|
||||
{
|
||||
return canReadConference();
|
||||
|
||||
} // end userCanRead
|
||||
|
||||
public boolean userCanPost()
|
||||
{
|
||||
return canPostToConference();
|
||||
|
||||
} // end userCanPost
|
||||
|
||||
public void touchUpdate(Connection conn, java.util.Date date) throws DataException
|
||||
{
|
||||
getConferenceData().touchUpdate(conn,date);
|
||||
|
||||
} // end getConferenceData
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static functions usable only from within the package
|
||||
*--------------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,706 @@
|
|||
/*
|
||||
* 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 Community 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.sql.*;
|
||||
import java.util.*;
|
||||
import org.apache.log4j.*;
|
||||
import com.silverwrist.venice.db.*;
|
||||
import com.silverwrist.venice.security.AuditRecord;
|
||||
import com.silverwrist.venice.core.*;
|
||||
|
||||
class TopicMessageUserContextImpl implements TopicMessageContext
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static Category logger = Category.getInstance(TopicMessageUserContextImpl.class.getName());
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private EngineBackend engine;
|
||||
private ConferenceBackend conf;
|
||||
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 boolean hidden;
|
||||
private int scribble_uid;
|
||||
private java.util.Date scribble_date;
|
||||
private String pseud;
|
||||
private int datalen;
|
||||
private String filename;
|
||||
private String mimetype;
|
||||
private boolean nuked = false;
|
||||
private String creator_cache = null;
|
||||
private String text_cache = null;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructors
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected TopicMessageUserContextImpl(EngineBackend engine, ConferenceBackend conf, DataPool datapool,
|
||||
long postid, long parent, int num, int linecount, int creator_uid,
|
||||
java.util.Date posted, boolean hidden, int scribble_uid,
|
||||
java.util.Date scribble_date, String pseud, int datalen,
|
||||
String filename, String mimetype)
|
||||
{
|
||||
this.engine = engine;
|
||||
this.conf = conf;
|
||||
this.datapool = datapool;
|
||||
this.postid = postid;
|
||||
this.parent = parent;
|
||||
this.num = num;
|
||||
this.linecount = linecount;
|
||||
this.creator_uid = creator_uid;
|
||||
this.posted = posted;
|
||||
this.hidden = hidden;
|
||||
this.scribble_uid = scribble_uid;
|
||||
this.scribble_date = scribble_date;
|
||||
this.pseud = pseud;
|
||||
this.datalen = datalen;
|
||||
this.filename = filename;
|
||||
this.mimetype = mimetype;
|
||||
|
||||
} // end constructor
|
||||
|
||||
TopicMessageUserContextImpl(EngineBackend engine, ConferenceBackend conf, DataPool datapool,
|
||||
long postid, long parent, int num, int linecount, int creator_uid,
|
||||
java.util.Date posted, String pseud)
|
||||
{
|
||||
this.engine = engine;
|
||||
this.conf = conf;
|
||||
this.datapool = datapool;
|
||||
this.postid = postid;
|
||||
this.parent = parent;
|
||||
this.num = num;
|
||||
this.linecount = linecount;
|
||||
this.creator_uid = creator_uid;
|
||||
this.posted = posted;
|
||||
this.hidden = false;
|
||||
this.scribble_uid = 0;
|
||||
this.scribble_date = null;
|
||||
this.pseud = pseud;
|
||||
this.datalen = 0;
|
||||
this.filename = null;
|
||||
this.mimetype = null;
|
||||
|
||||
} // 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
|
||||
|
||||
private void refresh(Connection conn) throws SQLException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
StringBuffer sql = new StringBuffer("SELECT p.hidden, p.scribble_uid, p.scribble_date, p.pseud, "
|
||||
+ "a.datalen, a.filename, a.mimetype FROM posts p LEFT JOIN "
|
||||
+ "postattach a ON p.postid = a.postid WHERE p.postid = ");
|
||||
sql.append(postid).append(';');
|
||||
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||
if (rs.next())
|
||||
{ // update a variety of fields
|
||||
hidden = rs.getBoolean(1);
|
||||
scribble_uid = rs.getInt(2);
|
||||
scribble_date = SQLUtil.getFullDateTime(rs,3);
|
||||
pseud = rs.getString(4);
|
||||
datalen = rs.getInt(5);
|
||||
filename = rs.getString(6);
|
||||
mimetype = rs.getString(7);
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // the post has been nuked - update accordingly
|
||||
linecount = 0;
|
||||
creator_uid = -1;
|
||||
posted = null;
|
||||
hidden = false;
|
||||
scribble_uid = -1;
|
||||
scribble_date = null;
|
||||
pseud = null;
|
||||
datalen = 0;
|
||||
filename = null;
|
||||
mimetype = null;
|
||||
nuked = true;
|
||||
creator_cache = null;
|
||||
text_cache = null;
|
||||
|
||||
} // end else
|
||||
|
||||
} // end refresh
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* 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
|
||||
if (nuked)
|
||||
return null; // post nuked!
|
||||
Connection conn = null;
|
||||
|
||||
try
|
||||
{ // use a database connection to get the user name
|
||||
conn = datapool.getConnection();
|
||||
refresh(conn);
|
||||
if (nuked)
|
||||
return null; // post nuked!
|
||||
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 hidden;
|
||||
|
||||
} // end isHidden
|
||||
|
||||
public boolean isScribbled()
|
||||
{
|
||||
return (scribble_date!=null);
|
||||
|
||||
} // end isScribbled
|
||||
|
||||
public boolean isNuked()
|
||||
{
|
||||
return nuked;
|
||||
|
||||
} // end isNuked
|
||||
|
||||
public java.util.Date getScribbleDate()
|
||||
{
|
||||
return scribble_date;
|
||||
|
||||
} // end getScribbleDate
|
||||
|
||||
public String getPseud()
|
||||
{
|
||||
return pseud;
|
||||
|
||||
} // return pseud
|
||||
|
||||
public String getBodyText() throws DataException
|
||||
{
|
||||
if (text_cache==null)
|
||||
{ // we don't have the body text yet, go get it
|
||||
Connection conn = null;
|
||||
if (nuked)
|
||||
return null; // post nuked!
|
||||
|
||||
try
|
||||
{ // use a database connection to get the body text
|
||||
conn = datapool.getConnection();
|
||||
refresh(conn);
|
||||
|
||||
if (nuked)
|
||||
return null; // post nuked!
|
||||
|
||||
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) + ";");
|
||||
if (rs.next())
|
||||
text_cache = rs.getString(1);
|
||||
else
|
||||
return "Data Missing"; // FUTURE: throw an exception?
|
||||
|
||||
} // end if
|
||||
else // for scribbled posts, we return the scribbler's name only
|
||||
text_cache = quickGetUserName(conn,scribble_uid);
|
||||
|
||||
} // 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 getBodyText
|
||||
|
||||
public boolean hasAttachment()
|
||||
{
|
||||
return (mimetype!=null);
|
||||
|
||||
} // end hasAttachment
|
||||
|
||||
public boolean canHide()
|
||||
{
|
||||
return ((creator_uid==conf.realUID()) || conf.userCanHide());
|
||||
|
||||
} // end canHide
|
||||
|
||||
public boolean canScribble()
|
||||
{
|
||||
return ((creator_uid==conf.realUID()) || conf.userCanScribble());
|
||||
|
||||
} // end canScribble
|
||||
|
||||
public boolean canNuke()
|
||||
{
|
||||
return conf.userCanNuke();
|
||||
|
||||
} // end canNuke
|
||||
|
||||
public void setHidden(boolean flag) throws DataException, AccessError
|
||||
{
|
||||
if ((creator_uid!=conf.realUID()) && !(conf.userCanHide()))
|
||||
{ // we can't change the hidden status!
|
||||
logger.error("trying to set hidden status of post w/o permission!");
|
||||
throw new AccessError("You are not permitted to change the hidden status of this message.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (nuked || (scribble_date!=null))
|
||||
return; // changing the status of a nuked or scribbled post is futile
|
||||
|
||||
Connection conn = null;
|
||||
AuditRecord ar = null;
|
||||
|
||||
try
|
||||
{ // open up a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// lock the tables we reference
|
||||
stmt.executeUpdate("LOCK TABLES posts WRITE, postattach READ;");
|
||||
try
|
||||
{ // first, make sure we have the right status for our post
|
||||
refresh(conn);
|
||||
if (nuked || (scribble_date!=null))
|
||||
return; // changing the status of a nuked or scribbled post is futile
|
||||
if (hidden==flag)
|
||||
return; // this is a no-op
|
||||
|
||||
// update the "hidden" flag in the database
|
||||
StringBuffer sql = new StringBuffer("UPDATE posts SET hidden = ");
|
||||
sql.append(flag ? '1' : '0').append(" WHERE postid = ").append(postid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
hidden = flag; // store flag
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // unlock the tables before we go
|
||||
Statement ulk_stmt = conn.createStatement();
|
||||
ulk_stmt.executeUpdate("UNLOCK TABLES;");
|
||||
|
||||
} // end finally
|
||||
|
||||
// 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");
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn this into a DataException
|
||||
logger.error("DB error setting hidden status: " + e.getMessage(),e);
|
||||
throw new DataException("unable to set hidden status: " + 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 setHidden
|
||||
|
||||
public void scribble() throws DataException, AccessError
|
||||
{
|
||||
if ((creator_uid!=conf.realUID()) && !(conf.userCanScribble()))
|
||||
{ // we can't scribble this post
|
||||
logger.error("trying to scribble post w/o permission!");
|
||||
throw new AccessError("You are not permitted to scribble this message.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (nuked || (scribble_date!=null))
|
||||
return; // scribbling a nuked or scribbled post is futile
|
||||
|
||||
Connection conn = null;
|
||||
AuditRecord ar = null;
|
||||
|
||||
try
|
||||
{ // open up a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// lock the tables we reference
|
||||
stmt.executeUpdate("LOCK TABLES posts WRITE, postdata WRITE, postattach WRITE;");
|
||||
try
|
||||
{ // first, make sure we have the right status for our post
|
||||
refresh(conn);
|
||||
if (nuked || (scribble_date!=null))
|
||||
return; // scribbling a nuked or scribbled post is futile
|
||||
|
||||
// First, set the appropriate "scribbled" information in the "header".
|
||||
StringBuffer sql = new StringBuffer("UPDATE posts SET linecount = 0, hidden = 0, scribble_uid = ");
|
||||
sql.append(conf.realUID()).append(", scribble_date = '");
|
||||
java.util.Date now = new java.util.Date();
|
||||
final String scribble_pseud = "<EM><B>(Scribbled)</B></EM>"; // TODO: configurable option
|
||||
sql.append(SQLUtil.encodeDate(now)).append("', pseud = '").append(scribble_pseud);
|
||||
sql.append("' WHERE postid = ").append(postid).append(';');
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
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) + ";");
|
||||
if (rs.next())
|
||||
{ // use this data to overwrite the post with X's
|
||||
int len = rs.getInt(1);
|
||||
if (len>0)
|
||||
{ // construct the "rubout" statement and execute it
|
||||
sql.setLength(0);
|
||||
sql.append("UPDATE postdata SET data = '");
|
||||
while (len>0)
|
||||
{ // generate a string of X's the length of the post
|
||||
sql.append('X');
|
||||
len--;
|
||||
|
||||
} // end while
|
||||
|
||||
sql.append("' WHERE postid = ").append(postid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
} // end if
|
||||
// else not much need to do a rubout
|
||||
|
||||
} // end if
|
||||
// else don't try...we're deleting the row anyway
|
||||
|
||||
// Delete the actual post data row.
|
||||
sql.setLength(0);
|
||||
sql.append("DELETE FROM postdata WHERE postid = ").append(postid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// Delete the attachment data row.
|
||||
// FUTURE: can we do an overwrite on the attachment the way we did on the post data?
|
||||
sql.setLength(0);
|
||||
sql.append("DELETE FROM postattach WHERE postid = ").append(postid).append(';');
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// Update our internal data fields.
|
||||
linecount = 0;
|
||||
hidden = false;
|
||||
scribble_uid = conf.realUID();
|
||||
scribble_date = now;
|
||||
pseud = scribble_pseud;
|
||||
text_cache = null;
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // unlock the tables before we go
|
||||
Statement ulk_stmt = conn.createStatement();
|
||||
ulk_stmt.executeUpdate("UNLOCK TABLES;");
|
||||
|
||||
} // end finally
|
||||
|
||||
// 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));
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn this into a DataException
|
||||
logger.error("DB error scribbling post: " + e.getMessage(),e);
|
||||
throw new DataException("unable to scribble message: " + 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 scribble
|
||||
|
||||
public void nuke() throws DataException, AccessError
|
||||
{
|
||||
if (!(conf.userCanNuke()))
|
||||
{ // we can't scribble this post
|
||||
logger.error("trying to nuke post w/o permission!");
|
||||
throw new AccessError("You are not permitted to nuke this message.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (nuked)
|
||||
return; // nuking a nuked post is futile
|
||||
|
||||
Connection conn = null;
|
||||
AuditRecord ar = null;
|
||||
|
||||
try
|
||||
{ // open up a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// lock the tables we reference
|
||||
stmt.executeUpdate("LOCK TABLES posts WRITE, postdata WRITE, postattach WRITE, postdogear WRITE;");
|
||||
|
||||
try
|
||||
{ // first, make sure we have the right status for our post
|
||||
refresh(conn);
|
||||
if (nuked)
|
||||
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) + ";");
|
||||
|
||||
// Update our internal variables.
|
||||
linecount = 0;
|
||||
creator_uid = -1;
|
||||
posted = null;
|
||||
hidden = false;
|
||||
scribble_uid = -1;
|
||||
scribble_date = null;
|
||||
pseud = null;
|
||||
datalen = 0;
|
||||
filename = null;
|
||||
mimetype = null;
|
||||
nuked = true;
|
||||
creator_cache = null;
|
||||
text_cache = null;
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // unlock the tables before we go
|
||||
Statement ulk_stmt = conn.createStatement();
|
||||
ulk_stmt.executeUpdate("UNLOCK TABLES;");
|
||||
|
||||
} // end finally
|
||||
|
||||
// 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));
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn this into a DataException
|
||||
logger.error("DB error nuking post: " + e.getMessage(),e);
|
||||
throw new DataException("unable to nuke message: " + 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 nuke
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static List loadMessageRange(EngineBackend engine, ConferenceBackend conf, DataPool datapool, int topicid,
|
||||
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) + "]");
|
||||
|
||||
Vector rc = new Vector();
|
||||
Connection conn = null; // pooled database connection
|
||||
|
||||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// run a query to get all the posts in a particular topic
|
||||
StringBuffer sql =
|
||||
new StringBuffer("SELECT p.postid, p.parent, p.num, p.linecount, p.creator_uid, p.posted, "
|
||||
+ "p.hidden, p.scribble_uid, p.scribble_date, p.pseud, a.datalen, a.filename, "
|
||||
+ "a.mimetype FROM posts p LEFT JOIN postattach a ON p.postid = a.postid "
|
||||
+ "WHERE p.topicid = ");
|
||||
sql.append(topicid).append(" AND p.num >= ").append(post_low).append(" AND p.num <= ");
|
||||
sql.append(post_high).append(" ORDER BY p.num ASC;");
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||
|
||||
while (rs.next())
|
||||
{ // create implementation objects and shove them into the return vector
|
||||
TopicMessageContext val =
|
||||
new TopicMessageUserContextImpl(engine,conf,datapool,rs.getLong(1),rs.getLong(2),rs.getInt(3),
|
||||
rs.getInt(4),rs.getInt(5),SQLUtil.getFullDateTime(rs,6),
|
||||
rs.getBoolean(7),rs.getInt(8),SQLUtil.getFullDateTime(rs,9),
|
||||
rs.getString(10),rs.getInt(11),rs.getString(12),rs.getString(13));
|
||||
rc.add(val);
|
||||
|
||||
} // end while
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn SQLException into data exception
|
||||
logger.error("DB error reading message entries: " + e.getMessage(),e);
|
||||
throw new DataException("unable to retrieve messages: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
{ // make sure we release the connection before we go
|
||||
if (conn!=null)
|
||||
datapool.releaseConnection(conn);
|
||||
|
||||
} // end finally
|
||||
|
||||
return new ReadOnlyVector(rc); // wrap the return vector
|
||||
|
||||
} // end loadMessageRange
|
||||
|
||||
} // end class TopicMessageUserContextImpl
|
|
@ -21,6 +21,7 @@ import java.sql.*;
|
|||
import java.util.*;
|
||||
import org.apache.log4j.*;
|
||||
import com.silverwrist.venice.db.*;
|
||||
import com.silverwrist.venice.htmlcheck.*;
|
||||
import com.silverwrist.venice.security.AuditRecord;
|
||||
import com.silverwrist.venice.core.*;
|
||||
|
||||
|
@ -109,11 +110,13 @@ class TopicUserContextImpl implements TopicContext
|
|||
private static ResultSet queryByTopic(Statement stmt, int topicid, int uid) throws SQLException
|
||||
{
|
||||
StringBuffer sql =
|
||||
new StringBuffer("SELECT t.topicid, t.num, t.creator_uid, t.top_message, t.frozen, t.archived, "
|
||||
+ "t.createdate, t.lastupdate, t.name, IFNULL(s.hidden,0) AS hidden, "
|
||||
+ "(t.top_message - IFNULL(s.last_message,-1)) AS unread FROM topics t "
|
||||
+ "LEFT JOIN topicsettings s ON t.topicid = s.topicid AND s.uid = ");
|
||||
sql.append(uid).append(" WHERE t.topicid = ").append(topicid).append(';');
|
||||
new StringBuffer("SELECT topics.topicid, topics.num, topics.creator_uid, topics.top_message, "
|
||||
+ "topics.frozen, topics.archived, topics.createdate, topics.lastupdate, "
|
||||
+ "topics.name, IFNULL(topicsettings.hidden,0) AS hidden, "
|
||||
+ "(topics.top_message - IFNULL(topicsettings.last_message,-1)) AS unread "
|
||||
+ "FROM topics LEFT JOIN topicsettings ON topics.topicid = topicsettings.topicid "
|
||||
+ "AND topicsettings.uid = ");
|
||||
sql.append(uid).append(" WHERE topics.topicid = ").append(topicid).append(';');
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
return stmt.executeQuery(sql.toString());
|
||||
|
@ -134,8 +137,29 @@ class TopicUserContextImpl implements TopicContext
|
|||
|
||||
} // end if
|
||||
|
||||
private void refresh(Connection conn) throws SQLException
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// perform a requery of the database
|
||||
ResultSet rs = queryByTopic(stmt,topicid,conf.realUID());
|
||||
if (rs.next())
|
||||
{ // update the fields that are capable of changing
|
||||
top_message = rs.getInt(4);
|
||||
frozen = rs.getBoolean(5);
|
||||
archived = rs.getBoolean(6);
|
||||
lastupdate = SQLUtil.getFullDateTime(rs,8);
|
||||
hidden = rs.getBoolean(10);
|
||||
unread = rs.getInt(11);
|
||||
|
||||
} // end if
|
||||
else // this topic must have been deleted - fsck it
|
||||
makeDeleted();
|
||||
|
||||
} // end refresh
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementatuions from interface TopicContext
|
||||
* Implementations from interface TopicContext
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -148,22 +172,7 @@ class TopicUserContextImpl implements TopicContext
|
|||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// perform a requery of the database
|
||||
ResultSet rs = queryByTopic(stmt,topicid,conf.realUID());
|
||||
if (rs.next())
|
||||
{ // update the fields that are capable of changing
|
||||
top_message = rs.getInt(4);
|
||||
frozen = rs.getBoolean(5);
|
||||
archived = rs.getBoolean(6);
|
||||
lastupdate = SQLUtil.getFullDateTime(rs,8);
|
||||
hidden = rs.getBoolean(10);
|
||||
unread = rs.getInt(11);
|
||||
|
||||
} // end if
|
||||
else // this topic must have been deleted - fsck it
|
||||
makeDeleted();
|
||||
refresh(conn);
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
|
@ -524,8 +533,8 @@ class TopicUserContextImpl implements TopicContext
|
|||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn SQLException into data exception
|
||||
logger.error("DB error setting topic data: " + e.getMessage(),e);
|
||||
throw new DataException("unable to set topic hidden status: " + e.getMessage(),e);
|
||||
logger.error("DB error setting topic user data: " + e.getMessage(),e);
|
||||
throw new DataException("unable to set unread messages: " + e.getMessage(),e);
|
||||
|
||||
} // end catch
|
||||
finally
|
||||
|
@ -543,6 +552,213 @@ class TopicUserContextImpl implements TopicContext
|
|||
|
||||
} // end fixSeen
|
||||
|
||||
public List getMessages(int low, int high) throws DataException, AccessError
|
||||
{
|
||||
if (!(conf.userCanRead()))
|
||||
{ // they can't read messages in this topic!
|
||||
logger.error("trying to read postings w/o permission!");
|
||||
throw new AccessError("You do not have permission to read messages in this conference.");
|
||||
|
||||
} // end if
|
||||
|
||||
// reorder parameters so they come in the correct order!
|
||||
if (low<=high)
|
||||
return TopicMessageUserContextImpl.loadMessageRange(engine,conf,datapool,topicid,low,high);
|
||||
else
|
||||
return TopicMessageUserContextImpl.loadMessageRange(engine,conf,datapool,topicid,high,low);
|
||||
|
||||
} // end getMessages
|
||||
|
||||
public TopicMessageContext postNewMessage(long parent, String pseud, String text)
|
||||
throws DataException, AccessError
|
||||
{
|
||||
if (!(conf.userCanPost()))
|
||||
{ // they can't post in this topic!
|
||||
logger.error("trying to post w/o permission!");
|
||||
throw new AccessError("You do not have permission to post messages in this conference.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (deleted)
|
||||
{ // the topic has been deleted
|
||||
logger.error("can't post to a deleted topic!");
|
||||
throw new AccessError("You cannot post to a topic that has been deleted.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (frozen && !(conf.userCanHide()))
|
||||
{ // can't post to a frozen topic!
|
||||
logger.error("can't post to a frozen topic!");
|
||||
throw new AccessError("The topic is frozen, and you do not have permission to post to it.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (archived && !(conf.userCanHide()))
|
||||
{ // can't post to a frozen topic!
|
||||
logger.error("can't post to an archived topic!");
|
||||
throw new AccessError("The topic is archived, and you do not have permission to post to it.");
|
||||
|
||||
} // end if
|
||||
|
||||
// preprocess the two arguments through HTML checkers
|
||||
HTMLChecker pseud_ch = engine.createCheckerObject(engine.HTMLC_POST_PSEUD);
|
||||
HTMLChecker text_ch = engine.createCheckerObject(engine.HTMLC_POST_BODY);
|
||||
try
|
||||
{ // run both arguments through the HTML checker
|
||||
pseud_ch.append(pseud);
|
||||
pseud_ch.finish();
|
||||
text_ch.append(text);
|
||||
text_ch.finish();
|
||||
|
||||
} // end try
|
||||
catch (AlreadyFinishedException e)
|
||||
{ // this isn't right...
|
||||
throw new InternalStateError("HTMLChecker erroneously throwing AlreadyFinishedException",e);
|
||||
|
||||
} // end catch
|
||||
|
||||
String real_pseud, real_text;
|
||||
int text_linecount;
|
||||
try
|
||||
{ // retrieve the processed values
|
||||
real_pseud = pseud_ch.getValue();
|
||||
real_text = text_ch.getValue();
|
||||
text_linecount = text_ch.getLines();
|
||||
|
||||
} // end try
|
||||
catch (NotYetFinishedException e)
|
||||
{ // this isn't right either!
|
||||
throw new InternalStateError("HTMLChecker erroneously throwing NotYetFinishedException",e);
|
||||
|
||||
} // end catch
|
||||
|
||||
int new_post_num;
|
||||
long new_post_id;
|
||||
java.util.Date posted_date;
|
||||
Connection conn = null;
|
||||
AuditRecord ar = null;
|
||||
|
||||
try
|
||||
{ // get a database connection
|
||||
conn = datapool.getConnection();
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// slap a lock on all the tables we need to touch
|
||||
stmt.executeUpdate("LOCK TABLES confs WRITE, topics WRITE, posts WRITE, postdata WRITE, "
|
||||
+ "confsettings WRITE, topicsettings READ;");
|
||||
|
||||
try
|
||||
{ // refresh our current status and recheck allowed status
|
||||
refresh(conn);
|
||||
if (deleted)
|
||||
{ // the topic has been deleted
|
||||
logger.error("can't post to a deleted topic!");
|
||||
throw new AccessError("You cannot post to a topic that has been deleted.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (frozen && !(conf.userCanHide()))
|
||||
{ // can't post to a frozen topic!
|
||||
logger.error("can't post to a frozen topic!");
|
||||
throw new AccessError("The topic is frozen, and you do not have permission to post to it.");
|
||||
|
||||
} // end if
|
||||
|
||||
if (archived && !(conf.userCanHide()))
|
||||
{ // can't post to a frozen topic!
|
||||
logger.error("can't post to an archived topic!");
|
||||
throw new AccessError("The topic is archived, and you do not have permission to post to it.");
|
||||
|
||||
} // end if
|
||||
|
||||
// Determine what the new post number is.
|
||||
new_post_num = top_message + 1;
|
||||
|
||||
// Add the post "header" to the posts table.
|
||||
StringBuffer sql = new StringBuffer("INSERT INTO posts (parent, topicid, num, linecount, creator_uid, "
|
||||
+ "posted, pseud) VALUES (");
|
||||
sql.append(parent).append(", ").append(topicid).append(", ").append(new_post_num).append(", ");
|
||||
sql.append(text_linecount).append(", ").append(conf.realUID()).append(", '");
|
||||
posted_date = new java.util.Date();
|
||||
sql.append(SQLUtil.encodeDate(posted_date)).append("', '").append(real_pseud).append("');");
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// Retrieve the new post ID.
|
||||
ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
|
||||
if (!(rs.next()))
|
||||
throw new InternalStateError("postMessage(): Unable to get new post ID!");
|
||||
new_post_id = rs.getLong(1);
|
||||
|
||||
// Touch the topic values to reflect the added post.
|
||||
sql.setLength(0);
|
||||
sql.append("UPDATE topics SET top_message = ").append(new_post_num).append(", lastupdate = '");
|
||||
sql.append(SQLUtil.encodeDate(posted_date)).append("' WHERE topicid = ").append(topicid).append(';');
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("SQL: " + sql.toString());
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// insert the post data
|
||||
sql.setLength(0);
|
||||
sql.append("INSERT INTO postdata (postid, data) VALUES (").append(new_post_id).append(", '");
|
||||
sql.append(real_text).append("');");
|
||||
stmt.executeUpdate(sql.toString());
|
||||
|
||||
// mark that we posted to the conference
|
||||
conf.touchUpdate(conn,posted_date);
|
||||
conf.touchPost(conn,posted_date);
|
||||
|
||||
// fill in our own local variables to reflect the update
|
||||
top_message = new_post_num;
|
||||
lastupdate = posted_date;
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // make sure we unlock the tables when we're done
|
||||
Statement ulk_stmt = conn.createStatement();
|
||||
ulk_stmt.executeUpdate("UNLOCK TABLES;");
|
||||
|
||||
} // end finally
|
||||
|
||||
// record what we did in an audit record
|
||||
ar = new AuditRecord(AuditRecord.POST_MESSAGE,conf.realUID(),conf.userRemoteAddress(),
|
||||
conf.realSIGID(),"conf=" + String.valueOf(conf.realConfID()) + ",topic="
|
||||
+ String.valueOf(topicid) + ",post=" + String.valueOf(new_post_id),
|
||||
"pseud=" + real_pseud);
|
||||
|
||||
} // end try
|
||||
catch (SQLException e)
|
||||
{ // turn SQLException into data exception
|
||||
logger.error("DB error posting message: " + e.getMessage(),e);
|
||||
throw new DataException("unable to post message: " + 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
|
||||
|
||||
// return the new message context
|
||||
return new TopicMessageUserContextImpl(engine,conf,datapool,new_post_id,parent,new_post_num,
|
||||
text_linecount,conf.realUID(),posted_date,real_pseud);
|
||||
|
||||
} // end postMessage
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External operations usable only from within the package
|
||||
*--------------------------------------------------------------------------------
|
||||
|
|
|
@ -25,7 +25,7 @@ class DictNode
|
|||
*/
|
||||
|
||||
private static final int[] permute_tab =
|
||||
{ 7, 21, 12, 9, 1, 13, 18, 10, 5, 25, 23, 11, 16, 3, 6, 14, 24, 4, 8, 2, 15, 20, 19, 22, 17, 26 };
|
||||
{ 8, 22, 13, 10, 2, 14, 19, 11, 6, 26, 24, 12, 17, 4, 7, 15, 25, 5, 9, 3, 16, 21, 20, 23, 18, 27 };
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
|
@ -53,6 +53,8 @@ class DictNode
|
|||
{
|
||||
if (ltr=='-')
|
||||
return 0;
|
||||
else if (ltr=='\'')
|
||||
return 1;
|
||||
else
|
||||
return permute_tab[ltr - 'a'];
|
||||
|
||||
|
|
|
@ -41,6 +41,62 @@ public class TreeLexicon implements ModSpellingDictionary
|
|||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Internal functions
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private boolean checkSimple(String word)
|
||||
{
|
||||
DictNode cur = root;
|
||||
for (int i=0; i<word.length(); i++)
|
||||
{ // loop through the characters and move down the trie
|
||||
char ch = word.charAt(i);
|
||||
if (((ch<'a') || (ch>'z')) && (ch!='-') && (ch!='\''))
|
||||
return false;
|
||||
cur = cur.getRef(ch);
|
||||
if (cur==null)
|
||||
return false;
|
||||
|
||||
} // end for
|
||||
|
||||
return cur.isTerminal();
|
||||
|
||||
} // end checkSimple
|
||||
|
||||
private boolean checkHyphenates(String word)
|
||||
{
|
||||
if (word.indexOf('-')<0)
|
||||
return false; // non-hyphenated
|
||||
|
||||
int st = 0;
|
||||
int p;
|
||||
boolean ok = true;
|
||||
do
|
||||
{ // break the word up into hyphenated compounds
|
||||
p = word.indexOf('-',st);
|
||||
String frag;
|
||||
if (p>=0)
|
||||
{ // get the middle fragment of the word
|
||||
frag = word.substring(st,p);
|
||||
st = p + 1;
|
||||
|
||||
} // end if
|
||||
else // get it from the end
|
||||
frag = word.substring(st);
|
||||
|
||||
// check this fragment...
|
||||
if (frag.length()<=1)
|
||||
ok = true; // fragments of length 0 or 1 are always OK
|
||||
else // anything else goes through checkSimple
|
||||
ok = checkSimple(frag);
|
||||
|
||||
} while (ok && (p>=0));
|
||||
|
||||
return ok;
|
||||
|
||||
} // end checkHyphenates
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface SpellingDictionary
|
||||
*--------------------------------------------------------------------------------
|
||||
|
@ -54,20 +110,22 @@ public class TreeLexicon implements ModSpellingDictionary
|
|||
|
||||
public synchronized boolean checkWord(String word)
|
||||
{
|
||||
if (word.length()<=1)
|
||||
return true; // words of length 1 get a free pass
|
||||
String real_word = word.toLowerCase();
|
||||
DictNode cur = root;
|
||||
for (int i=0; i<real_word.length(); i++)
|
||||
{ // loop through the characters and move down the trie
|
||||
char ch = real_word.charAt(i);
|
||||
if (((ch<'a') || (ch>'z')) && (ch!='-'))
|
||||
return false;
|
||||
cur = cur.getRef(ch);
|
||||
if (cur==null)
|
||||
return false;
|
||||
if (checkSimple(real_word))
|
||||
return true; // word is in lexicon - we're OK to go
|
||||
|
||||
} // end for
|
||||
if ((real_word.indexOf('\'')==(real_word.length()-2)) && (real_word.charAt(real_word.length()-1)=='s'))
|
||||
{ // drop the apostrophe-s from the end of the word and retry
|
||||
String base = real_word.substring(0,real_word.length()-2);
|
||||
if (checkSimple(base))
|
||||
return true;
|
||||
return checkHyphenates(base);
|
||||
|
||||
return cur.isTerminal();
|
||||
} // end if
|
||||
else // try hyphenated forms
|
||||
return checkHyphenates(real_word);
|
||||
|
||||
} // end checkWord
|
||||
|
||||
|
@ -83,7 +141,7 @@ public class TreeLexicon implements ModSpellingDictionary
|
|||
for (int i=0; i<real_word.length(); i++)
|
||||
{ // move through the word - bail out if bogus chars
|
||||
char ch = real_word.charAt(i);
|
||||
if (((ch<'a') || (ch>'z')) && (ch!='-'))
|
||||
if (((ch<'a') || (ch>'z')) && (ch!='-') && (ch!='\''))
|
||||
return;
|
||||
|
||||
// advance down through trie
|
||||
|
|
|
@ -79,6 +79,13 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
|||
private static final short ST_PAREN = 4;
|
||||
private static final short ST_TAGQUOTE = 5;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Internal constants
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static final int MARGIN_SLOP = 5;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
|
@ -127,17 +134,17 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
|||
|
||||
private static final boolean isWordChar(char ch)
|
||||
{
|
||||
return (Character.isUpperCase(ch) || Character.isLowerCase(ch) || (ch=='-'));
|
||||
return (Character.isUpperCase(ch) || Character.isLowerCase(ch) || (ch=='-') || (ch=='\''));
|
||||
|
||||
} // end isWordChar
|
||||
|
||||
private static final int getRunLength(StringBuffer buf)
|
||||
private static final int getRunLength(StringBuffer buf, int start)
|
||||
{
|
||||
boolean word_char = isWordChar(buf.charAt(0));
|
||||
boolean word_char = isWordChar(buf.charAt(start));
|
||||
int l = 1;
|
||||
while (l<buf.length())
|
||||
{ // see if there's a break from word characters to non-word characters
|
||||
if (isWordChar(buf.charAt(l))!=word_char)
|
||||
while ((start+l)<buf.length())
|
||||
{ // see if there's a break from word characters to non-word characters, or vice versa
|
||||
if (isWordChar(buf.charAt(start+l))!=word_char)
|
||||
break;
|
||||
l++;
|
||||
|
||||
|
@ -145,7 +152,13 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
|||
|
||||
return l;
|
||||
|
||||
} // end getStringRunLength
|
||||
} // end getRunLength
|
||||
|
||||
private static final int getRunLength(StringBuffer buf)
|
||||
{
|
||||
return getRunLength(buf,0);
|
||||
|
||||
} // end getRunLength
|
||||
|
||||
private void copyRewriters(Vector dest, List source)
|
||||
{
|
||||
|
@ -343,6 +356,7 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
|||
{ // calculate where the next line break is
|
||||
int line_break = temp_buffer.toString().indexOf('\n');
|
||||
int output_len = line_break;
|
||||
boolean force_line_break = false;
|
||||
if (output_len<0)
|
||||
output_len = temp_buffer.length();
|
||||
|
||||
|
@ -351,6 +365,8 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
|||
int remain_space = (int)(config.getWordWrapLength() - columns);
|
||||
if (remain_space<output_len)
|
||||
output_len = remain_space;
|
||||
if (output_len<=0) // this means that NONE of the whitespace would fit on this line...
|
||||
force_line_break = true; // we need a line break to fill in!
|
||||
|
||||
} // end if
|
||||
|
||||
|
@ -366,9 +382,14 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
|||
temp_buffer.setLength(0);
|
||||
|
||||
} // end if
|
||||
else // no more line breaks on this line - clear out the buffer
|
||||
else
|
||||
{ // no more line breaks on this line - clear out the buffer
|
||||
if (force_line_break)
|
||||
emitLineBreak(); // notice we can only force a line break if we didn't have one in the text
|
||||
temp_buffer.setLength(0);
|
||||
|
||||
} // end else
|
||||
|
||||
} // end while (still data in temp buffer)
|
||||
|
||||
} // end doFlushWhitespace
|
||||
|
@ -418,23 +439,25 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
|||
|
||||
} // end if
|
||||
|
||||
boolean first = true;
|
||||
while (temp_buffer.length()>0)
|
||||
{ // find the length of the initial string of word or non-word characters
|
||||
int sublen = getRunLength(temp_buffer);
|
||||
|
||||
if (isWordChar(temp_buffer.charAt(0)))
|
||||
{ // we need to check the word...but first, we must eliminate leading hyphens
|
||||
{ // we need to check the word...but first, we must eliminate leading hyphens and apostrophes
|
||||
int hyph_count = 0;
|
||||
while ((hyph_count<sublen) && (temp_buffer.charAt(hyph_count)=='-'))
|
||||
final String hyph_apos = "-\'";
|
||||
while ((hyph_count<sublen) && (hyph_apos.indexOf(temp_buffer.charAt(hyph_count))>=0))
|
||||
hyph_count++;
|
||||
emitFromStartOfTempBuffer(hyph_count);
|
||||
sublen -= hyph_count;
|
||||
|
||||
// now determine how many hyphens there are at the end of the word...
|
||||
// now determine how many hyphens/apostrophes there are at the end of the word...
|
||||
int word_len = sublen;
|
||||
hyph_count = 0;
|
||||
while ((word_len>0) && (temp_buffer.charAt(word_len-1)=='-'))
|
||||
{ // decrement word length, increment hyphen count
|
||||
while ((word_len>0) && (hyph_apos.indexOf(temp_buffer.charAt(word_len-1))>=0))
|
||||
{ // decrement word length, increment hyphen/apostrophe count
|
||||
hyph_count++;
|
||||
word_len--;
|
||||
|
||||
|
@ -458,13 +481,39 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
|||
|
||||
} // end if
|
||||
|
||||
// now emit the rest of the hyphens
|
||||
// now emit the rest of the hyphens/apostrophes
|
||||
emitFromStartOfTempBuffer(hyph_count);
|
||||
|
||||
} // end if
|
||||
else // just emit this many characters, line-breaking where required
|
||||
else
|
||||
{ // just emit this many characters, line-breaking where required
|
||||
if ((sublen==temp_buffer.length()) && !first && (sublen<=MARGIN_SLOP))
|
||||
{ // This is intended to handle a small run of non-word characters at the end of a string (i.e.
|
||||
// followed by whitespace) that should stay on the same line with its preceding word, to
|
||||
// eliminate "funnies" in punctuation formatting.
|
||||
emitString(temp_buffer.toString(),config.getOutputFilters(),true);
|
||||
temp_buffer.setLength(0);
|
||||
break;
|
||||
|
||||
} // end if
|
||||
|
||||
// This is kind of the inverse of the above check; if we have a small run of non-word
|
||||
// characters at the START of a word (preceded by whitespace and followed by at least
|
||||
// one word character), then ensure that we can keep that word and its prefixing non-word
|
||||
// characters on the same line (again, avoiding "funnies" in formatting).
|
||||
if ((sublen<temp_buffer.length()) && first && (sublen<=MARGIN_SLOP))
|
||||
{ // get the length of the word and ensure they can be kept together
|
||||
int fw_len = getRunLength(temp_buffer,sublen);
|
||||
ensureSpaceOnLine(sublen+fw_len);
|
||||
|
||||
} // end if
|
||||
|
||||
emitFromStartOfTempBuffer(sublen);
|
||||
|
||||
} // end else
|
||||
|
||||
first = false;
|
||||
|
||||
} // end while
|
||||
|
||||
} // end doFlushString
|
||||
|
@ -884,7 +933,8 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
|||
|
||||
} // end if
|
||||
|
||||
parse(str); // parse things
|
||||
if (str!=null)
|
||||
parse(str); // parse things
|
||||
|
||||
} // end append
|
||||
|
||||
|
|
|
@ -54,5 +54,9 @@ public interface Audit
|
|||
public static final int DELETE_TOPIC = 307;
|
||||
public static final int TOPIC_FREEZE = 308;
|
||||
public static final int TOPIC_ARCHIVE = 309;
|
||||
public static final int POST_MESSAGE = 310;
|
||||
public static final int HIDE_MESSAGE = 311;
|
||||
public static final int SCRIBBLE_MESSAGE = 312;
|
||||
public static final int NUKE_MESSAGE = 313;
|
||||
|
||||
} // end interface Audit
|
||||
|
|
|
@ -29,6 +29,47 @@ import com.silverwrist.venice.servlets.format.*;
|
|||
|
||||
public class ConfDisplay extends VeniceServlet
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Internal class used to get post number defaults
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static class PostInterval
|
||||
{
|
||||
private int first;
|
||||
private int last;
|
||||
|
||||
public PostInterval(int f, int l)
|
||||
{
|
||||
if (f<=l)
|
||||
{ // the sort is good
|
||||
first = f;
|
||||
last = l;
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // reverse the order
|
||||
first = l;
|
||||
last = f;
|
||||
|
||||
} // end else
|
||||
|
||||
} // end constructor
|
||||
|
||||
public int getFirst()
|
||||
{
|
||||
return first;
|
||||
|
||||
} // end getFirst
|
||||
|
||||
public int getLast()
|
||||
{
|
||||
return last;
|
||||
|
||||
} // end getLast
|
||||
|
||||
} // end class PostInterval
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
|
@ -183,6 +224,106 @@ public class ConfDisplay extends VeniceServlet
|
|||
|
||||
} // end getViewSortDefaults
|
||||
|
||||
private static PostInterval getInterval(ServletRequest request, TopicContext topic)
|
||||
throws ValidationException
|
||||
{
|
||||
int first, last;
|
||||
|
||||
String foo = request.getParameter("pxg");
|
||||
if (!(StringUtil.isStringEmpty(foo)))
|
||||
{ // we have a Go box parameter - try and decode it
|
||||
try
|
||||
{ // look for a range specifier
|
||||
int p = foo.indexOf('-');
|
||||
if (p<0)
|
||||
{ // single post number - try and use it
|
||||
first = Integer.parseInt(foo);
|
||||
last = first;
|
||||
|
||||
} // end if
|
||||
else if (p==0)
|
||||
{ // "-number" - works like "0-number"
|
||||
last = Integer.parseInt(foo.substring(1));
|
||||
first = 0;
|
||||
|
||||
} // end if
|
||||
else if (p==(foo.length()-1))
|
||||
{ // "number-" - works like "number-end"
|
||||
first = Integer.parseInt(foo.substring(0,p));
|
||||
last = topic.getTotalMessages() - 1;
|
||||
|
||||
} // end else if
|
||||
else
|
||||
{ // two numbers to decode
|
||||
first = Integer.parseInt(foo.substring(0,p));
|
||||
last = Integer.parseInt(foo.substring(p+1));
|
||||
|
||||
} // end else
|
||||
|
||||
return new PostInterval(first,last);
|
||||
|
||||
} // end try
|
||||
catch (NumberFormatException nfe)
|
||||
{ // if numeric conversion fails, just fall out and try to redisplay the other way
|
||||
} // end catch
|
||||
|
||||
} // end if
|
||||
|
||||
foo = request.getParameter("p1");
|
||||
if (StringUtil.isStringEmpty(foo))
|
||||
{ // no range specified - cook up a default one
|
||||
last = topic.getTotalMessages();
|
||||
int ur = topic.getUnreadMessages();
|
||||
if ((ur==0) || (ur>=20)) // TODO: configurable
|
||||
first = last - 20;
|
||||
else
|
||||
first = last - (ur+2);
|
||||
last--;
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // we have at least one parameter...
|
||||
try
|
||||
{ // convert it to an integer and range-limit it
|
||||
first = Integer.parseInt(foo);
|
||||
if (first<0)
|
||||
first = 0;
|
||||
else if (first>=topic.getTotalMessages())
|
||||
first = topic.getTotalMessages() - 1;
|
||||
|
||||
} // end try
|
||||
catch (NumberFormatException nfe)
|
||||
{ // we could not translate the parameter to a number
|
||||
throw new ValidationException("Message parameter is invalid.");
|
||||
|
||||
} // end catch
|
||||
|
||||
foo = request.getParameter("p2");
|
||||
if (StringUtil.isStringEmpty(foo))
|
||||
last = first; // just specify ONE post...
|
||||
else
|
||||
{ // OK, we have an actual "last message" parameter...
|
||||
try
|
||||
{ // convert it to an integer and range-limit it
|
||||
last = Integer.parseInt(foo);
|
||||
if ((last<0) || (last>=topic.getTotalMessages()))
|
||||
last = topic.getTotalMessages() - 1;
|
||||
|
||||
} // end try
|
||||
catch (NumberFormatException nfe)
|
||||
{ // we could not translate the parameter to a number
|
||||
throw new ValidationException("Message parameter is invalid.");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end else
|
||||
|
||||
} // end else
|
||||
|
||||
return new PostInterval(first,last);
|
||||
|
||||
} // end getInterval
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class HttpServlet
|
||||
*--------------------------------------------------------------------------------
|
||||
|
@ -287,7 +428,39 @@ public class ConfDisplay extends VeniceServlet
|
|||
if (logger.isDebugEnabled())
|
||||
logger.debug("MODE: display messages in topic");
|
||||
|
||||
// TODO: handle this somehow
|
||||
try
|
||||
{ // determine what the post interval is we want to display
|
||||
PostInterval piv = getInterval(request,topic);
|
||||
boolean read_new = !(StringUtil.isStringEmpty(request.getParameter("rnm")));
|
||||
boolean show_adv = !(StringUtil.isStringEmpty(request.getParameter("shac")));
|
||||
|
||||
// create the post display
|
||||
TopicPosts tpos = new TopicPosts(request,sig,conf,topic,piv.getFirst(),piv.getLast(),
|
||||
read_new,show_adv);
|
||||
content = tpos;
|
||||
page_title = topic.getName() + ": " + String.valueOf(topic.getTotalMessages()) + " Total; "
|
||||
+ String.valueOf(tpos.getNewMessages()) + " New; Last: "
|
||||
+ rdat.formatDateForDisplay(topic.getLastUpdateDate());
|
||||
|
||||
} // end try
|
||||
catch (ValidationException ve)
|
||||
{ // there's an error in the parameters somewhere
|
||||
page_title = "Error";
|
||||
content = new ErrorBox(null,ve.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
catch (DataException de)
|
||||
{ // there was a database error retrieving topics
|
||||
page_title = "Database Error";
|
||||
content = new ErrorBox(page_title,"Database error listing messages: " + de.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
catch (AccessError ae)
|
||||
{ // we were unable to retrieve the topic list
|
||||
page_title = "Access Error";
|
||||
content = new ErrorBox(page_title,ae.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end if
|
||||
else
|
||||
|
|
414
src/com/silverwrist/venice/servlets/PostMessage.java
Normal file
|
@ -0,0 +1,414 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
import org.apache.log4j.*;
|
||||
import com.silverwrist.util.StringUtil;
|
||||
import com.silverwrist.venice.ValidationException;
|
||||
import com.silverwrist.venice.core.*;
|
||||
import com.silverwrist.venice.servlets.format.*;
|
||||
|
||||
public class PostMessage extends VeniceServlet
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static Category logger = Category.getInstance(PostMessage.class.getName());
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Internal functions
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static SIGContext getSIGParameter(ServletRequest request, UserContext user)
|
||||
throws ValidationException, DataException
|
||||
{
|
||||
String str = request.getParameter("sig");
|
||||
if (str==null)
|
||||
{ // no SIG parameter - bail out now!
|
||||
logger.error("SIG parameter not specified!");
|
||||
throw new ValidationException("No SIG specified.");
|
||||
|
||||
} // end if
|
||||
|
||||
try
|
||||
{ // turn the string into a SIGID, and thence to a SIGContext
|
||||
int sigid = Integer.parseInt(str);
|
||||
return user.getSIGContext(sigid);
|
||||
|
||||
} // end try
|
||||
catch (NumberFormatException nfe)
|
||||
{ // error in Integer.parseInt
|
||||
logger.error("Cannot convert SIG parameter '" + str + "'!");
|
||||
throw new ValidationException("Invalid SIG parameter.");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end getSIGParameter
|
||||
|
||||
private static ConferenceContext getConferenceParameter(ServletRequest request, SIGContext sig)
|
||||
throws ValidationException, DataException, AccessError
|
||||
{
|
||||
String str = request.getParameter("conf");
|
||||
if (str==null)
|
||||
{ // no conference parameter - bail out now!
|
||||
logger.error("Conference parameter not specified!");
|
||||
throw new ValidationException("No conference specified.");
|
||||
|
||||
} // end if
|
||||
|
||||
try
|
||||
{ // turn the string into a ConfID, and thence to a ConferenceContext
|
||||
int confid = Integer.parseInt(str);
|
||||
return sig.getConferenceContext(confid);
|
||||
|
||||
} // end try
|
||||
catch (NumberFormatException nfe)
|
||||
{ // error in Integer.parseInt
|
||||
logger.error("Cannot convert conference parameter '" + str + "'!");
|
||||
throw new ValidationException("Invalid conference parameter.");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end getConferenceParameter
|
||||
|
||||
private static TopicContext getTopicParameter(ServletRequest request, ConferenceContext conf)
|
||||
throws ValidationException, DataException, AccessError
|
||||
{
|
||||
String str = request.getParameter("top");
|
||||
if (StringUtil.isStringEmpty(str))
|
||||
{ // no topic parameter - bail out now!
|
||||
logger.error("Topic parameter not specified!");
|
||||
throw new ValidationException("No topic specified.");
|
||||
|
||||
} // end if
|
||||
|
||||
try
|
||||
{ // turn the string into a TopicID, and thence to a TopicContext
|
||||
short topicid = Short.parseShort(str);
|
||||
return conf.getTopic(topicid);
|
||||
|
||||
} // end try
|
||||
catch (NumberFormatException nfe)
|
||||
{ // error in Integer.parseInt
|
||||
logger.error("Cannot convert topic parameter '" + str + "'!");
|
||||
throw new ValidationException("Invalid topic parameter.");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end getTopicParameter
|
||||
|
||||
private static int getPostNumber(ServletRequest request) throws ValidationException
|
||||
{
|
||||
String str = request.getParameter("sd");
|
||||
if (StringUtil.isStringEmpty(str))
|
||||
throw new ValidationException("Invalid parameter.");
|
||||
try
|
||||
{ // get the number of posts we think he topic has
|
||||
return Integer.parseInt(str);
|
||||
|
||||
} // end try
|
||||
catch (NumberFormatException nfe)
|
||||
{ // not a good integer...
|
||||
throw new ValidationException("Invalid parameter.");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end getPostNumber
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class HttpServlet
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public String getServletInfo()
|
||||
{
|
||||
String rc = "PostMessage servlet - Handles posting messages to a conference\n"
|
||||
+ "Part of the Venice Web Communities System\n";
|
||||
return rc;
|
||||
|
||||
} // end getServletInfo
|
||||
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
UserContext user = getUserContext(request);
|
||||
RenderData rdat = createRenderData(request,response);
|
||||
String page_title = null;
|
||||
Object content = null;
|
||||
SIGContext sig = null; // SIG context
|
||||
ConferenceContext conf = null; // conference context
|
||||
TopicContext topic = null; // topic context
|
||||
|
||||
try
|
||||
{ // this outer try is to catch ValidationException
|
||||
try
|
||||
{ // all commands require a SIG parameter
|
||||
sig = getSIGParameter(request,user);
|
||||
changeMenuSIG(request,sig);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("found SIG #" + String.valueOf(sig.getSIGID()));
|
||||
|
||||
} // end try
|
||||
catch (DataException de)
|
||||
{ // error looking up the SIG
|
||||
page_title = "Database Error";
|
||||
content = new ErrorBox(page_title,"Database error finding SIG: " + de.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
|
||||
if (content==null)
|
||||
{ // we got the SIG parameter OK
|
||||
try
|
||||
{ // all commands require a conference parameter
|
||||
conf = getConferenceParameter(request,sig);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("found conf #" + String.valueOf(conf.getConfID()));
|
||||
|
||||
} // end try
|
||||
catch (DataException de)
|
||||
{ // error looking up the conference
|
||||
page_title = "Database Error";
|
||||
content = new ErrorBox(page_title,"Database error finding conference: " + de.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end if
|
||||
|
||||
if (content==null)
|
||||
{ // we got the conference parameter OK
|
||||
try
|
||||
{ // now we need a topic parameter
|
||||
topic = getTopicParameter(request,conf);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("found topic #" + String.valueOf(topic.getTopicID()));
|
||||
|
||||
} // end try
|
||||
catch (DataException de)
|
||||
{ // error looking up the conference
|
||||
page_title = "Database Error";
|
||||
content = new ErrorBox(page_title,"Database error finding topic: " + de.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end if
|
||||
|
||||
} // end try
|
||||
catch (ValidationException ve)
|
||||
{ // these all get handled in pretty much the same way
|
||||
page_title = "Error";
|
||||
content = new ErrorBox(null,ve.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
catch (AccessError ae)
|
||||
{ // these all get handled in pretty much the same way
|
||||
page_title = "Access Error";
|
||||
content = new ErrorBox(page_title,ae.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
|
||||
if (content==null)
|
||||
{ // make sure we've got some post data
|
||||
String raw_postdata = request.getParameter("pb");
|
||||
if (StringUtil.isStringEmpty(raw_postdata))
|
||||
{ // don't allow zero-size posts
|
||||
rdat.nullResponse();
|
||||
return;
|
||||
|
||||
} // end if
|
||||
|
||||
final String yes = "Y";
|
||||
|
||||
// now decide what to do based on which button got clicked
|
||||
if (isImageButtonClicked(request,"cancel"))
|
||||
{ // canceled posting - take us back to familiar ground
|
||||
rdat.redirectTo("confdisp?sig=" + String.valueOf(sig.getSIGID()) + "&conf="
|
||||
+ String.valueOf(conf.getConfID()) + "&top="
|
||||
+ String.valueOf(topic.getTopicNumber()));
|
||||
return;
|
||||
|
||||
} // end if ("Cancel")
|
||||
else if (isImageButtonClicked(request,"preview"))
|
||||
{ // previewing the post!
|
||||
try
|
||||
{ // generate a preview view
|
||||
content = new PostPreview(getVeniceEngine(),sig,conf,topic,request.getParameter("pseud"),
|
||||
raw_postdata,request.getParameter("next"),getPostNumber(request),
|
||||
yes.equals(request.getParameter("attach")));
|
||||
page_title = "Previewing Post";
|
||||
|
||||
} // end try
|
||||
catch (ValidationException ve)
|
||||
{ // there was some sort of a parameter error in the display (getPostNumber can throw this)
|
||||
page_title = "Error";
|
||||
content = new ErrorBox(null,ve.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end else if ("Preview & Spellcheck")
|
||||
else if (isImageButtonClicked(request,"post"))
|
||||
{ // post the message, and then reload the same topic
|
||||
try
|
||||
{ // first, check against slippage
|
||||
int pn = getPostNumber(request);
|
||||
if (pn==topic.getTotalMessages())
|
||||
{ // no slippage - post the message!!!
|
||||
TopicMessageContext msg = topic.postNewMessage(0,request.getParameter("pseud"),raw_postdata);
|
||||
if (yes.equals(request.getParameter("attach")))
|
||||
{ // we have an attachment to upload...
|
||||
// TODO: do something to upload the attachment
|
||||
rdat.redirectTo("confdisp?sig=" + String.valueOf(sig.getSIGID()) + "&conf="
|
||||
+ String.valueOf(conf.getConfID()) + "&top="
|
||||
+ String.valueOf(topic.getTopicNumber()) + "&rnm=1");
|
||||
return;
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // no attachment - jump back to the topic
|
||||
rdat.redirectTo("confdisp?sig=" + String.valueOf(sig.getSIGID()) + "&conf="
|
||||
+ String.valueOf(conf.getConfID()) + "&top="
|
||||
+ String.valueOf(topic.getTopicNumber()) + "&rnm=1");
|
||||
return;
|
||||
|
||||
} // end else
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // slippage detected - show the slippage display
|
||||
content = new PostSlippage(getVeniceEngine(),sig,conf,topic,pn,request.getParameter("next"),
|
||||
request.getParameter("pseud"),raw_postdata,
|
||||
yes.equals(request.getParameter("attach")));
|
||||
page_title = "Slippage or Double-Click Detected";
|
||||
|
||||
} // end else
|
||||
|
||||
} // end try
|
||||
catch (ValidationException ve)
|
||||
{ // there was some sort of a parameter error in the display
|
||||
page_title = "Error";
|
||||
content = new ErrorBox(null,ve.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
catch (DataException de)
|
||||
{ // there was a database error posting the message
|
||||
page_title = "Database Error";
|
||||
content = new ErrorBox(page_title,"Database error posting message: " + de.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
catch (AccessError ae)
|
||||
{ // we were unable to retrieve the topic list
|
||||
page_title = "Access Error";
|
||||
content = new ErrorBox(page_title,ae.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end else if ("Post & Reload")
|
||||
else if (isImageButtonClicked(request,"postnext"))
|
||||
{ // post the message, and then go to the "next" topic
|
||||
try
|
||||
{ // first, check against slippage
|
||||
int pn = getPostNumber(request);
|
||||
if (pn==topic.getTotalMessages())
|
||||
{ // no slippage - post the message!
|
||||
TopicMessageContext msg = topic.postNewMessage(0,request.getParameter("pseud"),raw_postdata);
|
||||
|
||||
short next;
|
||||
try
|
||||
{ // attempt to get the value of the "next topic" parameter
|
||||
String foo = request.getParameter("next");
|
||||
if (StringUtil.isStringEmpty(foo))
|
||||
next = topic.getTopicNumber();
|
||||
else
|
||||
next = Short.parseShort(foo);
|
||||
|
||||
} // end try
|
||||
catch (NumberFormatException nfe)
|
||||
{ // just default me
|
||||
next = topic.getTopicNumber();
|
||||
|
||||
} // end catch
|
||||
|
||||
if (yes.equals(request.getParameter("attach")))
|
||||
{ // we have an attachment to upload...
|
||||
// TODO: jump somewhere we can upload the attachment!
|
||||
rdat.redirectTo("confdisp?sig=" + String.valueOf(sig.getSIGID()) + "&conf="
|
||||
+ String.valueOf(conf.getConfID()) + "&top=" + String.valueOf(next) + "&rnm=1");
|
||||
return;
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // no attachment - jump to the next topic
|
||||
rdat.redirectTo("confdisp?sig=" + String.valueOf(sig.getSIGID()) + "&conf="
|
||||
+ String.valueOf(conf.getConfID()) + "&top=" + String.valueOf(next) + "&rnm=1");
|
||||
return;
|
||||
|
||||
} // end else
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // slippage detected - show the slippage display
|
||||
content = new PostSlippage(getVeniceEngine(),sig,conf,topic,pn,request.getParameter("next"),
|
||||
request.getParameter("pseud"),raw_postdata,
|
||||
yes.equals(request.getParameter("attach")));
|
||||
page_title = "Slippage or Double-Click Detected";
|
||||
|
||||
} // end else
|
||||
|
||||
} // end try
|
||||
catch (ValidationException ve)
|
||||
{ // there was some sort of a parameter error in the display
|
||||
page_title = "Error";
|
||||
content = new ErrorBox(null,ve.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
catch (DataException de)
|
||||
{ // there was a database error posting the message
|
||||
page_title = "Database Error";
|
||||
content = new ErrorBox(page_title,"Database error posting message: " + de.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
catch (AccessError ae)
|
||||
{ // we were unable to retrieve the topic list
|
||||
page_title = "Access Error";
|
||||
content = new ErrorBox(page_title,ae.getMessage(),"top");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end else if ("Post & Go Next")
|
||||
else
|
||||
{ // unknown button clicked
|
||||
page_title = "Internal Error";
|
||||
logger.error("no known button click on PostMessage.doPost");
|
||||
content = new ErrorBox(page_title,"Unknown command button pressed","top");
|
||||
|
||||
} // end else
|
||||
|
||||
} // end if (got all parameters oK)
|
||||
|
||||
BaseJSPData basedat = new BaseJSPData(page_title,"post",content);
|
||||
basedat.transfer(getServletContext(),rdat);
|
||||
|
||||
} // end doPost
|
||||
|
||||
} // end class PostMessage
|
190
src/com/silverwrist/venice/servlets/format/PostPreview.java
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.venice.servlets.format;
|
||||
|
||||
import java.util.*;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
import com.silverwrist.util.StringUtil;
|
||||
import com.silverwrist.venice.htmlcheck.*;
|
||||
import com.silverwrist.venice.core.*;
|
||||
|
||||
public class PostPreview implements JSPRender
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// Attribute name for request attribute
|
||||
protected static final String ATTR_NAME = "com.silverwrist.venice.content.PostPreview";
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private SIGContext sig;
|
||||
private ConferenceContext conf;
|
||||
private TopicContext topic;
|
||||
private String next;
|
||||
private String pseud;
|
||||
private String data;
|
||||
private String preview;
|
||||
private int num_errors;
|
||||
private int msgs;
|
||||
private boolean attach;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public PostPreview(VeniceEngine engine, SIGContext sig, ConferenceContext conf, TopicContext topic,
|
||||
String pseud, String data, String next, int msgs, boolean attach)
|
||||
{
|
||||
this.sig = sig;
|
||||
this.conf = conf;
|
||||
this.topic = topic;
|
||||
this.next = next;
|
||||
this.msgs = msgs;
|
||||
this.attach = attach;
|
||||
|
||||
try
|
||||
{ // sanitize the pseud data
|
||||
HTMLChecker check = engine.getEscapingChecker();
|
||||
check.append(pseud);
|
||||
check.finish();
|
||||
this.pseud = check.getValue();
|
||||
|
||||
// sanitize the post box data
|
||||
check.reset();
|
||||
check.append(data);
|
||||
check.finish();
|
||||
this.data = check.getValue();
|
||||
|
||||
// now generate the preview
|
||||
check = engine.getPreviewChecker();
|
||||
check.append(data);
|
||||
check.finish();
|
||||
this.preview = check.getValue();
|
||||
this.num_errors = check.getCounter("spelling");
|
||||
|
||||
} // end try
|
||||
catch (HTMLCheckerException e)
|
||||
{ // this is a bad issue...
|
||||
throw new InternalStateError("spurious HTMLCheckerException thrown");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static functions
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public static PostPreview retrieve(ServletRequest request)
|
||||
{
|
||||
return (PostPreview)(request.getAttribute(ATTR_NAME));
|
||||
|
||||
} // end retrieve
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface JSPRender
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void store(ServletRequest request)
|
||||
{
|
||||
request.setAttribute(ATTR_NAME,this);
|
||||
|
||||
} // end store
|
||||
|
||||
public String getTargetJSPName()
|
||||
{
|
||||
return "preview.jsp";
|
||||
|
||||
} // end getTargetJSPName
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public int getNumSpellingErrors()
|
||||
{
|
||||
return num_errors;
|
||||
|
||||
} // end getNumSpellingErrors
|
||||
|
||||
public String getPreviewData()
|
||||
{
|
||||
return preview;
|
||||
|
||||
} // end getPreviewData
|
||||
|
||||
public int getSIGID()
|
||||
{
|
||||
return sig.getSIGID();
|
||||
|
||||
} // end getSIGID
|
||||
|
||||
public int getConfID()
|
||||
{
|
||||
return conf.getConfID();
|
||||
|
||||
} // end getConfID
|
||||
|
||||
public int getTopicNumber()
|
||||
{
|
||||
return topic.getTopicNumber();
|
||||
|
||||
} // end getTopicNumber
|
||||
|
||||
public int getTotalMessages()
|
||||
{
|
||||
return msgs;
|
||||
|
||||
} // end getTotalMessages
|
||||
|
||||
public String getNextVal()
|
||||
{
|
||||
return next;
|
||||
|
||||
} // end getNextVal
|
||||
|
||||
public String getPseud()
|
||||
{
|
||||
return pseud;
|
||||
|
||||
} // end getPseud
|
||||
|
||||
public boolean attachChecked()
|
||||
{
|
||||
return attach;
|
||||
|
||||
} // end attachChecked
|
||||
|
||||
public String getBodyText()
|
||||
{
|
||||
return data;
|
||||
|
||||
} // end getBodyText
|
||||
|
||||
} // end class PostPreview
|
216
src/com/silverwrist/venice/servlets/format/PostSlippage.java
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.venice.servlets.format;
|
||||
|
||||
import java.util.*;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
import com.silverwrist.util.StringUtil;
|
||||
import com.silverwrist.venice.htmlcheck.*;
|
||||
import com.silverwrist.venice.core.*;
|
||||
|
||||
public class PostSlippage implements JSPRender
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// Attribute name for request attribute
|
||||
protected static final String ATTR_NAME = "com.silverwrist.venice.content.PostSlippage";
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private SIGContext sig;
|
||||
private ConferenceContext conf;
|
||||
private TopicContext topic;
|
||||
private List messages;
|
||||
private String next;
|
||||
private String pseud;
|
||||
private String text;
|
||||
private boolean attach;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public PostSlippage(VeniceEngine engine, SIGContext sig, ConferenceContext conf, TopicContext topic,
|
||||
int lastval, String next, String pseud, String text, boolean attach)
|
||||
throws DataException, AccessError
|
||||
{
|
||||
this.sig = sig;
|
||||
this.conf = conf;
|
||||
this.topic = topic;
|
||||
this.messages = topic.getMessages(lastval,topic.getTotalMessages()-1);
|
||||
this.next = next;
|
||||
this.attach = attach;
|
||||
|
||||
try
|
||||
{ // run the text and pseud through an HTML checker to escape them
|
||||
HTMLChecker ch = engine.getEscapingChecker();
|
||||
ch.append(pseud);
|
||||
ch.finish();
|
||||
this.pseud = ch.getValue();
|
||||
ch.reset();
|
||||
ch.append(text);
|
||||
ch.finish();
|
||||
this.text = text;
|
||||
|
||||
} // end try
|
||||
catch (HTMLCheckerException e)
|
||||
{ // this shouldn't happen
|
||||
throw new InternalStateError("spurious HTMLCheckerException thrown");
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static functions
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public static PostSlippage retrieve(ServletRequest request)
|
||||
{
|
||||
return (PostSlippage)(request.getAttribute(ATTR_NAME));
|
||||
|
||||
} // end retrieve
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface JSPRender
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void store(ServletRequest request)
|
||||
{
|
||||
request.setAttribute(ATTR_NAME,this);
|
||||
|
||||
} // end store
|
||||
|
||||
public String getTargetJSPName()
|
||||
{
|
||||
return "slippage.jsp";
|
||||
|
||||
} // end getTargetJSPName
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* 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 getSIGID()
|
||||
{
|
||||
return sig.getSIGID();
|
||||
|
||||
} // end getSIGID
|
||||
|
||||
public int getConfID()
|
||||
{
|
||||
return conf.getConfID();
|
||||
|
||||
} // end getConfID
|
||||
|
||||
public int getTopicNumber()
|
||||
{
|
||||
return topic.getTopicNumber();
|
||||
|
||||
} // end getTopicNumber
|
||||
|
||||
public String getTopicName()
|
||||
{
|
||||
return topic.getName();
|
||||
|
||||
} // end getTopicName
|
||||
|
||||
public String getIdentifyingData()
|
||||
{
|
||||
return "Slippage posting to topic " + String.valueOf(topic.getTopicID());
|
||||
|
||||
} // end getIdentifyingData
|
||||
|
||||
public int getTotalMessages()
|
||||
{
|
||||
return topic.getTotalMessages();
|
||||
|
||||
} // end getTotalMessages
|
||||
|
||||
public Iterator getMessageIterator()
|
||||
{
|
||||
return messages.iterator();
|
||||
|
||||
} // end getMessageIterator
|
||||
|
||||
public String getNextVal()
|
||||
{
|
||||
return next;
|
||||
|
||||
} // end getNextVal
|
||||
|
||||
public String getPseud()
|
||||
{
|
||||
return pseud;
|
||||
|
||||
} // end getPseud
|
||||
|
||||
public boolean attachChecked()
|
||||
{
|
||||
return attach;
|
||||
|
||||
} // end attachChecked
|
||||
|
||||
public String getBodyText()
|
||||
{
|
||||
return text;
|
||||
|
||||
} // end getBodyText
|
||||
|
||||
} // end class PostSlippage
|
|
@ -106,6 +106,14 @@ public class TopicListing implements JSPRender
|
|||
|
||||
} // end getConfID
|
||||
|
||||
public String getLocator()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("sig=");
|
||||
buf.append(sig.getSIGID()).append("&conf=").append(conf.getConfID());
|
||||
return buf.toString();
|
||||
|
||||
} // end getLocator
|
||||
|
||||
public String getConfName()
|
||||
{
|
||||
return conf.getName();
|
||||
|
@ -118,6 +126,15 @@ public class TopicListing implements JSPRender
|
|||
|
||||
} // end canDoReadNew
|
||||
|
||||
public String getNextLocator()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("sig=");
|
||||
buf.append(sig.getSIGID()).append("&conf=").append(conf.getConfID()).append("&top=");
|
||||
buf.append(visit_order.getNext());
|
||||
return buf.toString();
|
||||
|
||||
} // end getNextLocator
|
||||
|
||||
public boolean canCreateTopic()
|
||||
{
|
||||
return conf.canCreateTopic();
|
||||
|
|
354
src/com/silverwrist/venice/servlets/format/TopicPosts.java
Normal file
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.venice.servlets.format;
|
||||
|
||||
import java.util.*;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
import com.silverwrist.util.StringUtil;
|
||||
import com.silverwrist.venice.core.*;
|
||||
|
||||
public class TopicPosts implements JSPRender
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// Attribute name for request attribute
|
||||
protected static final String ATTR_NAME = "com.silverwrist.venice.content.TopicPosts";
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private SIGContext sig;
|
||||
private ConferenceContext conf;
|
||||
private TopicContext topic;
|
||||
private int first;
|
||||
private int last;
|
||||
private boolean show_advanced;
|
||||
private int unread;
|
||||
private List messages;
|
||||
private TopicVisitOrder visit_order;
|
||||
private String cache_locator = null;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public TopicPosts(HttpServletRequest request, SIGContext sig, ConferenceContext conf, TopicContext topic,
|
||||
int first, int last, boolean read_new, boolean show_advanced)
|
||||
throws DataException, AccessError
|
||||
{
|
||||
this.sig = sig;
|
||||
this.conf = conf;
|
||||
this.topic = topic;
|
||||
this.first = first;
|
||||
this.last = last;
|
||||
this.show_advanced = show_advanced;
|
||||
this.unread = topic.getUnreadMessages();
|
||||
if (read_new)
|
||||
topic.setUnreadMessages(0);
|
||||
this.messages = topic.getMessages(first,last);
|
||||
this.visit_order = TopicVisitOrder.retrieve(request.getSession(true),conf.getConfID());
|
||||
visit_order.visit(topic.getTopicNumber());
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static functions
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public static TopicPosts retrieve(ServletRequest request)
|
||||
{
|
||||
return (TopicPosts)(request.getAttribute(ATTR_NAME));
|
||||
|
||||
} // end retrieve
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface JSPRender
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void store(ServletRequest request)
|
||||
{
|
||||
request.setAttribute(ATTR_NAME,this);
|
||||
|
||||
} // end store
|
||||
|
||||
public String getTargetJSPName()
|
||||
{
|
||||
return "posts.jsp";
|
||||
|
||||
} // end getTargetJSPName
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* 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 getSIGID()
|
||||
{
|
||||
return sig.getSIGID();
|
||||
|
||||
} // end getSIGID
|
||||
|
||||
public int getConfID()
|
||||
{
|
||||
return conf.getConfID();
|
||||
|
||||
} // end getConfID
|
||||
|
||||
public int getTopicNumber()
|
||||
{
|
||||
return topic.getTopicNumber();
|
||||
|
||||
} // end getTopicNumber
|
||||
|
||||
public int getNextTopicNumber()
|
||||
{
|
||||
return visit_order.getNext();
|
||||
|
||||
} // end getNextTopicNumber
|
||||
|
||||
public String getConfLocator()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("sig=");
|
||||
buf.append(sig.getSIGID()).append("&conf=").append(conf.getConfID());
|
||||
return buf.toString();
|
||||
|
||||
} // end getConfLocator
|
||||
|
||||
public String getLocator()
|
||||
{
|
||||
if (cache_locator==null)
|
||||
{ // build up the standard locator
|
||||
StringBuffer buf = new StringBuffer("sig=");
|
||||
buf.append(sig.getSIGID()).append("&conf=").append(conf.getConfID()).append("&top=");
|
||||
buf.append(topic.getTopicNumber());
|
||||
cache_locator = buf.toString();
|
||||
|
||||
} // end if
|
||||
|
||||
return cache_locator;
|
||||
|
||||
} // end getLocator
|
||||
|
||||
public String getNextLocator()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("sig=");
|
||||
buf.append(sig.getSIGID()).append("&conf=").append(conf.getConfID()).append("&top=");
|
||||
buf.append(visit_order.getNext());
|
||||
return buf.toString();
|
||||
|
||||
} // end getNextLocator
|
||||
|
||||
public String getIdentifyingData()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("Posts ");
|
||||
buf.append(first).append(" through ").append(last).append(" in topic #").append(topic.getTopicID());
|
||||
return buf.toString();
|
||||
|
||||
} // end getIdentifyingData
|
||||
|
||||
public String getTopicName()
|
||||
{
|
||||
return topic.getName();
|
||||
|
||||
} // end getTopicName
|
||||
|
||||
public int getTotalMessages()
|
||||
{
|
||||
return topic.getTotalMessages();
|
||||
|
||||
} // end getTotalMessages
|
||||
|
||||
public int getNewMessages()
|
||||
{
|
||||
return unread;
|
||||
|
||||
} // end getNewMessages
|
||||
|
||||
public Date getLastUpdate()
|
||||
{
|
||||
return topic.getLastUpdateDate();
|
||||
|
||||
} // end getLastUpdate
|
||||
|
||||
public boolean isTopicHidden()
|
||||
{
|
||||
return topic.isHidden();
|
||||
|
||||
} // end isTopicHidden
|
||||
|
||||
public boolean canDoNextTopic()
|
||||
{
|
||||
return visit_order.isNext();
|
||||
|
||||
} // end canDoNextTopic
|
||||
|
||||
public boolean canFreezeTopic()
|
||||
{
|
||||
return topic.canFreeze();
|
||||
|
||||
} // end canFreezeTopic
|
||||
|
||||
public boolean isTopicFrozen()
|
||||
{
|
||||
return topic.isFrozen();
|
||||
|
||||
} // end isTopicFrozen
|
||||
|
||||
public boolean canArchiveTopic()
|
||||
{
|
||||
return topic.canArchive();
|
||||
|
||||
} // end canArchiveTopic
|
||||
|
||||
public boolean isTopicArchived()
|
||||
{
|
||||
return topic.isArchived();
|
||||
|
||||
} // end isTopicArchived
|
||||
|
||||
public boolean canDeleteTopic()
|
||||
{
|
||||
return false; // TODO: fix me
|
||||
|
||||
} // end canDeleteTopic
|
||||
|
||||
public boolean canScrollUp()
|
||||
{
|
||||
return (first>0);
|
||||
|
||||
} // end canScrollUp
|
||||
|
||||
public String getScrollUpLocator()
|
||||
{
|
||||
int new_first = first - 20; // TODO: configurable
|
||||
int new_last = last - 1;
|
||||
if (new_first<0)
|
||||
{ // normalize so we start at 0
|
||||
new_last += (-new_first);
|
||||
new_first = 0;
|
||||
|
||||
} // end if
|
||||
|
||||
StringBuffer buf = new StringBuffer("p1=");
|
||||
buf.append(new_first).append("&p2=").append(new_last);
|
||||
return buf.toString();
|
||||
|
||||
} // end getScrollUpLocator
|
||||
|
||||
public boolean canScrollDown()
|
||||
{
|
||||
return ((topic.getTotalMessages() - (1 + last))>=20); // TODO: configurable
|
||||
|
||||
} // end canScrollDown
|
||||
|
||||
public String getScrollDownLocator()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("p1=");
|
||||
buf.append(last+1).append("&p2=").append(last+20); // TODO: configurable
|
||||
return buf.toString();
|
||||
|
||||
} // end getScrollDownLocator
|
||||
|
||||
public boolean canScrollToEnd()
|
||||
{
|
||||
return ((topic.getTotalMessages() - (1 + last))>0);
|
||||
|
||||
} // end canScrollToEnd
|
||||
|
||||
public String getScrollToEndLocator()
|
||||
{
|
||||
int my_last = topic.getTotalMessages();
|
||||
StringBuffer buf = new StringBuffer("p1=");
|
||||
buf.append(my_last-20).append("&p2=").append(my_last-1); // TODO: configurable
|
||||
return buf.toString();
|
||||
|
||||
} // end getScrollToEndLocator
|
||||
|
||||
public Iterator getMessageIterator()
|
||||
{
|
||||
return messages.iterator();
|
||||
|
||||
} // end getMessageIterator()
|
||||
|
||||
public boolean emitBreakLinePoint(int msg)
|
||||
{
|
||||
return (msg==(topic.getTotalMessages()-unread));
|
||||
|
||||
} // end emitBreakLinePoint
|
||||
|
||||
public boolean showAdvanced()
|
||||
{
|
||||
return show_advanced && (last==first);
|
||||
|
||||
} // end showAdvanced
|
||||
|
||||
public boolean displayPostBox()
|
||||
{
|
||||
boolean flag1 = conf.canPostToConference();
|
||||
boolean flag2 = (topic.isFrozen() ? topic.canFreeze() : true);
|
||||
boolean flag3 = (topic.isArchived() ? topic.canArchive() : true);
|
||||
return flag1 && flag2 && flag3;
|
||||
|
||||
} // end displayPostBox
|
||||
|
||||
public String getDefaultPseud()
|
||||
{
|
||||
return conf.getDefaultPseud();
|
||||
|
||||
} // end getDefaultPseud
|
||||
|
||||
} // end class TopicPosts
|
327
web/format/posts.jsp
Normal file
|
@ -0,0 +1,327 @@
|
|||
<%--
|
||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
(the "License"); you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
language governing rights and limitations under the License.
|
||||
|
||||
The Original Code is the Venice Web Communities System.
|
||||
|
||||
The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
--%>
|
||||
<%@ page import = "java.util.*" %>
|
||||
<%@ page import = "com.silverwrist.util.StringUtil" %>
|
||||
<%@ page import = "com.silverwrist.venice.core.*" %>
|
||||
<%@ page import = "com.silverwrist.venice.servlets.Variables" %>
|
||||
<%@ page import = "com.silverwrist.venice.servlets.format.*" %>
|
||||
<%
|
||||
TopicPosts data = TopicPosts.retrieve(request);
|
||||
Variables.failIfNull(data);
|
||||
RenderData rdat = RenderConfig.createRenderData(application,request,response);
|
||||
%>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- <%= data.getIdentifyingData() %> --><% } %>
|
||||
<%
|
||||
String tmp;
|
||||
if (data.isTopicArchived())
|
||||
tmp = "(Archived) ";
|
||||
else if (data.isTopicFrozen())
|
||||
tmp = "(Frozen) ";
|
||||
else
|
||||
tmp = "";
|
||||
rdat.writeContentHeader(out,data.getTopicName(),tmp + String.valueOf(data.getTotalMessages())
|
||||
+ " Total; " + String.valueOf(data.getNewMessages()) + " New; Last: "
|
||||
+ rdat.formatDateForDisplay(data.getLastUpdate()));
|
||||
%>
|
||||
<TABLE BORDER=0 WIDTH="100%" CELLPADDING=0 CELLSPACING=0>
|
||||
<TR VALIGN=BOTTOM>
|
||||
<TD NOWRAP ALIGN=LEFT>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- Topic user controls section --><% } %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getConfLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_topic_list.gif") %>" ALT="Topic List" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
|
||||
<% if (data.isTopicHidden()) { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_show_topic.gif") %>" ALT="Show Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% } else { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_hide_topic.gif") %>" ALT="Hide Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% } // end if %>
|
||||
|
||||
<% if (data.canDoNextTopic()) { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator() + "&rnm=1") %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_next_topic.gif") %>" ALT="Next Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
|
||||
<% if (data.getNewMessages()>0) { %>
|
||||
<%-- TODO: this doesn't do Keep New yet --%>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator() + "&rnm=1") %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_next_keep_new.gif") %>" ALT="Next & Keep New" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
|
||||
<% } // end if %>
|
||||
<% } // end if %>
|
||||
</TD>
|
||||
<TD NOWRAP ALIGN=RIGHT>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- Topic admin controls section --><% } %>
|
||||
<% if (data.canFreezeTopic()) { %>
|
||||
|
||||
<% if (data.isTopicFrozen()) { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_unfreeze_topic.gif") %>" ALT="Unfreeze Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% } else { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_freeze_topic.gif") %>" ALT="Freeze Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% } // end if %>
|
||||
<% } // end if %>
|
||||
<% if (data.canArchiveTopic()) { %>
|
||||
|
||||
<% if (data.isTopicArchived()) { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_unarchive_topic.gif") %>" ALT="Unarchive Topic" WIDTH=80
|
||||
HEIGHT=24 BORDER=0></A>
|
||||
<% } else { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_archive_topic.gif") %>" ALT="Archive Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% } // end if %>
|
||||
<% } // end if %>
|
||||
<% if (data.canDeleteTopic()) { %>
|
||||
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_delete_topic.gif") %>" ALT="Delete Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% } // end if %>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR><TD COLSPAN=2> </TD></TR>
|
||||
<TR VALIGN=BOTTOM>
|
||||
<TD NOWRAP ALIGN=LEFT>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- Go box --><% } %>
|
||||
<FORM METHOD="GET" ACTION="<%= rdat.getEncodedServletPath("confdisp") %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="sig" VALUE="<%= data.getSIGID() %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="conf" VALUE="<%= data.getConfID() %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="top" VALUE="<%= data.getTopicNumber() %>">
|
||||
<INPUT TYPE="TEXT" NAME="pxg" VALUE="" SIZE=6 MAXLENGTH=13>
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_go.gif") %>" NAME="Go" ALT="Go"
|
||||
ALIGN=BOTTOM WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
</FORM>
|
||||
</TD>
|
||||
<TD NOWRAP ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- Upper navigation linkset --><% } %>
|
||||
<%-- TODO: the number "20" should be configurable --%>
|
||||
<A NAME="top">[</A>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&p1=0&p2=-1") %>">View All</A>
|
||||
<% if (data.canScrollUp()) { %>
|
||||
|
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
|
||||
+ data.getScrollUpLocator()) %>">Scroll Up 20</A>
|
||||
<% } // end if %>
|
||||
<% if (data.canScrollDown()) { %>
|
||||
|
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
|
||||
+ data.getScrollDownLocator()) %>">Scroll Down 20</A>
|
||||
<% } // end if %>
|
||||
<% if (data.canScrollDown()) { %>
|
||||
|
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
|
||||
+ data.getScrollToEndLocator()) %>">Scroll To End</A>
|
||||
<% } // end if %>
|
||||
|
|
||||
<A HREF="#bottom">Bottom</A>
|
||||
]
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<% if (rdat.useHTMLComments()) { %><!-- Begin Actual Messages --><% } %>
|
||||
<%
|
||||
Iterator it = data.getMessageIterator();
|
||||
String last_post = rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&p1="
|
||||
+ String.valueOf(data.getTotalMessages() - 1));
|
||||
boolean can_line = false;
|
||||
%>
|
||||
<% while (it.hasNext()) { %>
|
||||
<%
|
||||
TopicMessageContext msg = (TopicMessageContext)(it.next());
|
||||
String poster = data.getPosterName(msg);
|
||||
%>
|
||||
<% if (can_line && data.emitBreakLinePoint(msg.getPostNumber())) { %><HR WIDTH="70%"><% } %>
|
||||
<% if (data.showAdvanced()) { %>
|
||||
<BR>
|
||||
<TABLE WIDTH="100%" BORDER=0 CELLPADDING=0 CELLSPACING=0><TR VALIGN=TOP><TD NOWRAP ALIGN=LEFT>
|
||||
<% } // end if %>
|
||||
<%= rdat.getStdFontTag(null,2) %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&p1="
|
||||
+ String.valueOf(msg.getPostNumber())) %>"><%= msg.getPostNumber() %></A> of
|
||||
<A HREF="<%= last_post %>"><%= data.getTotalMessages() - 1 %></A>
|
||||
<%= rdat.getStdFontTag(null,1) %><<%= "TODO" %>></FONT><BR>
|
||||
<B><%= msg.getPseud() %></B>
|
||||
(<EM>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("user/" + poster) %>" TARGET="_blank"><%= poster %></A>,
|
||||
<%= rdat.formatDateForDisplay(msg.getPostDate()) %>
|
||||
</EM>)
|
||||
<%-- TODO: paperclip goes here if we have an attachment --%>
|
||||
</FONT><P>
|
||||
<% if (msg.isScribbled()) { %>
|
||||
<TT><EM><B>
|
||||
(Scribbled by <%= data.getMessageBodyText(msg) %> on
|
||||
<%= rdat.formatDateForDisplay(msg.getScribbleDate()) %>)
|
||||
</B></EM></TT>
|
||||
<% } else if (msg.isHidden() && !(data.showAdvanced())) { %>
|
||||
<TT><EM><B>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&p1="
|
||||
+ String.valueOf(msg.getPostNumber())) %>">(Hidden
|
||||
Message: <%= msg.getNumLines() %> <% if (msg.getNumLines()==1) { %>Line<% } else { %>Lines<% } %></A>
|
||||
</B></EM></TT>
|
||||
<% } else { %>
|
||||
<PRE><%= data.getMessageBodyText(msg) %></PRE>
|
||||
<% } // end if %>
|
||||
<% if (data.showAdvanced()) { %>
|
||||
</TD><TD NOWRAP ALIGN=RIGHT>
|
||||
<% if (!(msg.isScribbled())) { %>
|
||||
<% if (msg.canHide()) { %>
|
||||
<% if (msg.isHidden()) { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_show.gif") %>" ALT="Show" WIDTH=80 HEIGHT=24 BORDER=0></A><P>
|
||||
<% } else { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_hide.gif") %>" ALT="Hide" WIDTH=80 HEIGHT=24 BORDER=0></A><P>
|
||||
<% } // end if %>
|
||||
<% } // end if (can hide) %>
|
||||
<% if (msg.canScribble()) { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_scribble.gif") %>" ALT="Scribble" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A><P>
|
||||
<% } // end if (can scribble) %>
|
||||
<% } // end if (not already scribbled) %>
|
||||
<% if (msg.canNuke()) { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_nuke.gif") %>" ALT="Nuke" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A><P>
|
||||
<% } // end if (can nuke) %>
|
||||
</TD></TR></TABLE><BR>
|
||||
<% } // end if (showing advanced controls) %>
|
||||
<% can_line = true; %>
|
||||
<% } // end while %>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- End Actual Messages --><% } %>
|
||||
|
||||
<TABLE BORDER=0 WIDTH="100%" CELLPADDING=0 CELLSPACING=0>
|
||||
<TR VALIGN=BOTTOM>
|
||||
<TD NOWRAP ALIGN=LEFT> </TD>
|
||||
<TD NOWRAP ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- Upper navigation linkset --><% } %>
|
||||
<%-- TODO: the number "20" should be configurable --%>
|
||||
<A NAME="bottom">[</A>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&p1=0&p2=-1") %>">View All</A>
|
||||
<% if (data.canScrollUp()) { %>
|
||||
|
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
|
||||
+ data.getScrollUpLocator()) %>">Scroll Up 20</A>
|
||||
<% } // end if %>
|
||||
<% if (data.canScrollDown()) { %>
|
||||
|
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
|
||||
+ data.getScrollDownLocator()) %>">Scroll Down 20</A>
|
||||
<% } // end if %>
|
||||
<% if (data.canScrollDown()) { %>
|
||||
|
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&"
|
||||
+ data.getScrollToEndLocator()) %>">Scroll To End</A>
|
||||
<% } // end if %>
|
||||
|
|
||||
<A HREF="#top">Top</A>
|
||||
]
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<TR VALIGN=BOTTOM>
|
||||
<TD NOWRAP ALIGN=LEFT>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- Topic user controls section --><% } %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getConfLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_topic_list.gif") %>" ALT="Topic List" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
|
||||
<% if (data.isTopicHidden()) { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_show_topic.gif") %>" ALT="Show Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% } else { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("TODO?" + data.getLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_hide_topic.gif") %>" ALT="Hide Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% } // end if %>
|
||||
|
||||
<% if (data.canDoNextTopic()) { %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator() + "&rnm=1") %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_next_topic.gif") %>" ALT="Next Topic" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
|
||||
<% if (data.getNewMessages()>0) { %>
|
||||
<%-- TODO: this doesn't do Keep New yet --%>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator() + "&rnm=1") %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_next_keep_new.gif") %>" ALT="Next & Keep New" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
|
||||
<% } // end if %>
|
||||
<% } // end if %>
|
||||
</TD>
|
||||
<TD NOWRAP ALIGN=RIGHT> </TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<% if (data.displayPostBox()) { %>
|
||||
<HR><%= rdat.getStdFontTag(null,3) %><B>Post Message in "<%= data.getTopicName() %>":</B></FONT>
|
||||
<BR>
|
||||
<FORM METHOD="POST" ACTION="<%= rdat.getEncodedServletPath("post") %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="sig" VALUE="<%= data.getSIGID() %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="conf" VALUE="<%= data.getConfID() %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="top" VALUE="<%= data.getTopicNumber() %>">
|
||||
<% if (data.canDoNextTopic()) { %>
|
||||
<INPUT TYPE="HIDDEN" NAME="next" VALUE="<%= data.getNextTopicNumber() %>">
|
||||
<% } // end if %>
|
||||
<INPUT TYPE="HIDDEN" NAME="sd" VALUE="<%= data.getTotalMessages() %>">
|
||||
<TABLE BORDER=0 CELLPADDING=0>
|
||||
<TR><TD ALIGN=LEFT COLSPAN=2>
|
||||
<%= rdat.getStdFontTag(null,2) %>Your name/header:</FONT><BR>
|
||||
<INPUT TYPE="TEXT" NAME="pseud" SIZE=37 MAXLENGTH=255 VALUE="<%= data.getDefaultPseud() %>">
|
||||
<%= rdat.getStdFontTag(null,2) %><INPUT TYPE="CHECKBOX" NAME="attach" VALUE="Y"> Attach a file</FONT>
|
||||
</TD></TR>
|
||||
<TR>
|
||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>Message:</FONT></TD>
|
||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||
<A HREF="TODO" TARGET="_blank">HTML Guide</A>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<TR><TD ALIGN=LEFT COLSPAN=2>
|
||||
<TEXTAREA NAME="pb" WRAP=SOFT ROWS=7 COLS=51></TEXTAREA>
|
||||
</TD></TR>
|
||||
<TR><TD ALIGN=CENTER COLSPAN=2>
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_preview.gif") %>" ALT="Preview" NAME="preview"
|
||||
WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_reload.gif") %>" ALT="Post & Reload"
|
||||
NAME="post" WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
<% if (data.canDoNextTopic()) { %>
|
||||
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_go_next.gif") %>" ALT="Post & Go Next"
|
||||
NAME="postnext" WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
<% } // end if %>
|
||||
</TD></TR>
|
||||
</TABLE>
|
||||
</FORM>
|
||||
<% } else if (data.isTopicArchived()) { %>
|
||||
<DIV ALIGN=CENTER><%= rdat.getStdFontTag(null,2) %><B>This is an <EM>Archived</EM> Topic</B></DIV>
|
||||
<% } else if (data.isTopicFrozen()) { %>
|
||||
<DIV ALIGN=CENTER><%= rdat.getStdFontTag(null,2) %><B>This is a <EM>Frozen</EM> Topic</B></DIV>
|
||||
<% } // end if %>
|
||||
<% rdat.writeFooter(out); %>
|
81
web/format/preview.jsp
Normal file
|
@ -0,0 +1,81 @@
|
|||
<%--
|
||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
(the "License"); you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
language governing rights and limitations under the License.
|
||||
|
||||
The Original Code is the Venice Web Communities System.
|
||||
|
||||
The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
--%>
|
||||
<%@ page import = "java.util.*" %>
|
||||
<%@ page import = "com.silverwrist.util.StringUtil" %>
|
||||
<%@ page import = "com.silverwrist.venice.core.*" %>
|
||||
<%@ page import = "com.silverwrist.venice.servlets.Variables" %>
|
||||
<%@ page import = "com.silverwrist.venice.servlets.format.*" %>
|
||||
<%
|
||||
PostPreview data = PostPreview.retrieve(request);
|
||||
Variables.failIfNull(data);
|
||||
RenderData rdat = RenderConfig.createRenderData(application,request,response);
|
||||
%>
|
||||
<% rdat.writeContentHeader(out,"Previewing Post",null); %>
|
||||
<%= rdat.getStdFontTag(null,3) %><B>
|
||||
<% if (data.getNumSpellingErrors()==0) { %>
|
||||
Your post did not contain any spelling errors.
|
||||
<% } else if (data.getNumSpellingErrors()==1) { %>
|
||||
There was 1 spelling error in your post.
|
||||
<% } else { %>
|
||||
There were <%= data.getNumSpellingErrors() %> spelling errors in your post.
|
||||
<% } // end if %>
|
||||
</B></FONT>
|
||||
<P><PRE><%= data.getPreviewData() %></PRE><HR>
|
||||
|
||||
<FORM METHOD="POST" ACTION="<%= rdat.getEncodedServletPath("post") %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="sig" VALUE="<%= data.getSIGID() %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="conf" VALUE="<%= data.getConfID() %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="top" VALUE="<%= data.getTopicNumber() %>">
|
||||
<% if (!(StringUtil.isStringEmpty(data.getNextVal()))) { %>
|
||||
<INPUT TYPE="HIDDEN" NAME="next" VALUE="<%= data.getNextVal() %>">
|
||||
<% } // end if %>
|
||||
<INPUT TYPE="HIDDEN" NAME="sd" VALUE="<%= data.getTotalMessages() %>">
|
||||
<TABLE BORDER=0 CELLPADDING=0>
|
||||
<TR><TD ALIGN=LEFT COLSPAN=2>
|
||||
<%= rdat.getStdFontTag(null,2) %>Your name/header:</FONT><BR>
|
||||
<INPUT TYPE="TEXT" NAME="pseud" SIZE=37 MAXLENGTH=255 VALUE="<%= data.getPseud() %>">
|
||||
<%= rdat.getStdFontTag(null,2) %><INPUT TYPE="CHECKBOX" NAME="attach"
|
||||
VALUE="Y" <% if (data.attachChecked()) { %>CHECKED<% } %> > Attach a file</FONT>
|
||||
</TD></TR>
|
||||
<TR>
|
||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>Message:</FONT></TD>
|
||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||
<A HREF="TODO" TARGET="_blank">HTML Guide</A>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<TR><TD ALIGN=LEFT COLSPAN=2>
|
||||
<TEXTAREA NAME="pb" WRAP=SOFT ROWS=7 COLS=51><%= data.getBodyText() %></TEXTAREA>
|
||||
</TD></TR>
|
||||
<TR><TD ALIGN=CENTER COLSPAN=2>
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_preview.gif") %>" ALT="Preview" NAME="preview"
|
||||
WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_reload.gif") %>" ALT="Post & Reload"
|
||||
NAME="post" WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
<% if (!(StringUtil.isStringEmpty(data.getNextVal()))) { %>
|
||||
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_go_next.gif") %>" ALT="Post & Go Next"
|
||||
NAME="postnext" WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
<% } // end if %>
|
||||
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_cancel.gif") %>" ALT="Cancel"
|
||||
NAME="cancel" WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
</TD></TR>
|
||||
</TABLE>
|
||||
</FORM>
|
||||
<% rdat.writeFooter(out); %>
|
107
web/format/slippage.jsp
Normal file
|
@ -0,0 +1,107 @@
|
|||
<%--
|
||||
The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
(the "License"); you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
language governing rights and limitations under the License.
|
||||
|
||||
The Original Code is the Venice Web Communities System.
|
||||
|
||||
The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
--%>
|
||||
<%@ page import = "java.util.*" %>
|
||||
<%@ page import = "com.silverwrist.util.StringUtil" %>
|
||||
<%@ page import = "com.silverwrist.venice.core.*" %>
|
||||
<%@ page import = "com.silverwrist.venice.servlets.Variables" %>
|
||||
<%@ page import = "com.silverwrist.venice.servlets.format.*" %>
|
||||
<%
|
||||
PostSlippage data = PostSlippage.retrieve(request);
|
||||
Variables.failIfNull(data);
|
||||
RenderData rdat = RenderConfig.createRenderData(application,request,response);
|
||||
%>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- <%= data.getIdentifyingData() %> --><% } %>
|
||||
<% rdat.writeContentHeader(out,"Slippage or Double-Click Detected",null); %>
|
||||
<%= rdat.getStdFontTag(null,2) %>
|
||||
The following posts slipped in while you were typing. You may choose to edit your message and
|
||||
re-post, just post it as is, or cancel your posting altogether.
|
||||
</FONT>
|
||||
|
||||
<% if (rdat.useHTMLComments()) { %><!-- Begin Slipped Messages --><% } %>
|
||||
<% Iterator it = data.getMessageIterator(); %>
|
||||
<% while (it.hasNext()) { %>
|
||||
<%
|
||||
TopicMessageContext msg = (TopicMessageContext)(it.next());
|
||||
String poster = data.getPosterName(msg);
|
||||
%>
|
||||
<%= rdat.getStdFontTag(null,2) %>
|
||||
<B><%= msg.getPostNumber() %></B> of <B><%= data.getTotalMessages() - 1 %></B>
|
||||
<%= rdat.getStdFontTag(null,1) %><<%= "TODO" %>></FONT><BR>
|
||||
<B><%= msg.getPseud() %></B>
|
||||
(<EM>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("user/" + poster) %>" TARGET="_blank"><%= poster %></A>,
|
||||
<%= rdat.formatDateForDisplay(msg.getPostDate()) %>
|
||||
</EM>)
|
||||
</FONT><P>
|
||||
<% if (msg.isScribbled()) { %>
|
||||
<TT><EM><B>
|
||||
(Scribbled by <%= data.getMessageBodyText(msg) %> on
|
||||
<%= rdat.formatDateForDisplay(msg.getScribbleDate()) %>)
|
||||
</B></EM></TT>
|
||||
<% } else { %>
|
||||
<PRE><%= data.getMessageBodyText(msg) %></PRE>
|
||||
<% } // end if %>
|
||||
<% } // end while %>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- End Slipped Messages --><% } %>
|
||||
|
||||
<HR><%= rdat.getStdFontTag(null,3) %><B>Post Message in "<%= data.getTopicName() %>":</B></FONT>
|
||||
<BR>
|
||||
<FORM METHOD="POST" ACTION="<%= rdat.getEncodedServletPath("post") %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="sig" VALUE="<%= data.getSIGID() %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="conf" VALUE="<%= data.getConfID() %>">
|
||||
<INPUT TYPE="HIDDEN" NAME="top" VALUE="<%= data.getTopicNumber() %>">
|
||||
<% if (!(StringUtil.isStringEmpty(data.getNextVal()))) { %>
|
||||
<INPUT TYPE="HIDDEN" NAME="next" VALUE="<%= data.getNextVal() %>">
|
||||
<% } // end if %>
|
||||
<INPUT TYPE="HIDDEN" NAME="sd" VALUE="<%= data.getTotalMessages() %>">
|
||||
<TABLE BORDER=0 CELLPADDING=0>
|
||||
<TR><TD ALIGN=LEFT COLSPAN=2>
|
||||
<%= rdat.getStdFontTag(null,2) %>Your name/header:</FONT><BR>
|
||||
<INPUT TYPE="TEXT" NAME="pseud" SIZE=37 MAXLENGTH=255 VALUE="<%= data.getPseud() %>">
|
||||
<%= rdat.getStdFontTag(null,2) %><INPUT TYPE="CHECKBOX" NAME="attach"
|
||||
VALUE="Y" <% if (data.attachChecked()) { %>CHECKED<% } %> > Attach a file</FONT>
|
||||
</TD></TR>
|
||||
<TR>
|
||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>Message:</FONT></TD>
|
||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||
<A HREF="TODO" TARGET="_blank">HTML Guide</A>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<TR><TD ALIGN=LEFT COLSPAN=2>
|
||||
<TEXTAREA NAME="pb" WRAP=SOFT ROWS=7 COLS=51><%= data.getBodyText() %></TEXTAREA>
|
||||
</TD></TR>
|
||||
<TR><TD ALIGN=CENTER COLSPAN=2>
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_preview.gif") %>" ALT="Preview" NAME="preview"
|
||||
WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_reload.gif") %>" ALT="Post & Reload"
|
||||
NAME="post" WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
<% if (!(StringUtil.isStringEmpty(data.getNextVal()))) { %>
|
||||
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_post_go_next.gif") %>" ALT="Post & Go Next"
|
||||
NAME="postnext" WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
<% } // end if %>
|
||||
|
||||
<INPUT TYPE="IMAGE" SRC="<%= rdat.getFullImagePath("bn_cancel.gif") %>" ALT="Cancel"
|
||||
NAME="cancel" WIDTH=80 HEIGHT=24 BORDER=0>
|
||||
</TD></TR>
|
||||
</TABLE>
|
||||
</FORM>
|
||||
<% rdat.writeFooter(out); %>
|
||||
|
||||
|
|
@ -24,8 +24,7 @@
|
|||
TopicListing data = TopicListing.retrieve(request);
|
||||
Variables.failIfNull(data);
|
||||
RenderData rdat = RenderConfig.createRenderData(application,request,response);
|
||||
String self = "confdisp?sig=" + String.valueOf(data.getSIGID()) + "&conf="
|
||||
+ String.valueOf(data.getConfID());
|
||||
String self = "confdisp?" + data.getLocator();
|
||||
String tmp;
|
||||
%>
|
||||
<% if (rdat.useHTMLComments()) { %><!-- Topic list for conf #<%= data.getConfID() %> --><% } %>
|
||||
|
@ -36,14 +35,14 @@
|
|||
SRC="<%= rdat.getFullImagePath("bn_conference_list.gif") %>" ALT="Conference List" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% if (data.canCreateTopic()) { %>
|
||||
<% tmp = "confops?sig=" + String.valueOf(data.getSIGID()) + "&conf="
|
||||
+ String.valueOf(data.getConfID()) + "&cmd=T"; %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>"><IMG SRC="<%= rdat.getFullImagePath("bn_add_topic.gif") %>"
|
||||
ALT="Add Topic" WIDTH=80 HEIGHT=24 BORDER=0></A>
|
||||
<% tmp = rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=T"); %>
|
||||
<A HREF="<%= tmp %>"><IMG SRC="<%= rdat.getFullImagePath("bn_add_topic.gif") %>" ALT="Add Topic"
|
||||
WIDTH=80 HEIGHT=24 BORDER=0></A>
|
||||
<% } // end if %>
|
||||
<% if (data.canDoReadNew()) { %>
|
||||
<A HREF="TODO"><IMG SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>"
|
||||
ALT="Read New" WIDTH=80 HEIGHT=24 BORDER=0></A>
|
||||
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator()) %>"><IMG
|
||||
SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>" ALT="Read New" WIDTH=80 HEIGHT=24
|
||||
BORDER=0></A>
|
||||
<% } // end if %>
|
||||
<A HREF="TODO"><IMG SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>"
|
||||
ALT="Manage" WIDTH=80 HEIGHT=24 BORDER=0></A>
|
||||
|
@ -59,52 +58,61 @@
|
|||
<% tmp = self + "&sort="
|
||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_NUMBER) ? -ConferenceContext.SORT_NUMBER
|
||||
: ConferenceContext.SORT_NUMBER); %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>">#</A>
|
||||
<B><A HREF="<%= rdat.getEncodedServletPath(tmp) %>">#</A></B>
|
||||
</FONT></TD>
|
||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
||||
<% tmp = self + "&sort="
|
||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_NAME) ? -ConferenceContext.SORT_NAME
|
||||
: ConferenceContext.SORT_NAME); %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>">Topic Name</A>
|
||||
<B><A HREF="<%= rdat.getEncodedServletPath(tmp) %>">Topic Name</A></B>
|
||||
</FONT></TD>
|
||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||
<% tmp = self + "&sort="
|
||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_UNREAD) ? -ConferenceContext.SORT_UNREAD
|
||||
: ConferenceContext.SORT_UNREAD); %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>">New</A>
|
||||
<B><A HREF="<%= rdat.getEncodedServletPath(tmp) %>">New</A></B>
|
||||
</FONT></TD>
|
||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||
<% tmp = self + "&sort="
|
||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_TOTAL) ? -ConferenceContext.SORT_TOTAL
|
||||
: ConferenceContext.SORT_TOTAL); %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>">Total</A>
|
||||
<B><A HREF="<%= rdat.getEncodedServletPath(tmp) %>">Total</A></B>
|
||||
</FONT></TD>
|
||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
||||
<% tmp = self + "&sort="
|
||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_DATE) ? -ConferenceContext.SORT_DATE
|
||||
: ConferenceContext.SORT_DATE); %>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>">Last Response</A>
|
||||
<B><A HREF="<%= rdat.getEncodedServletPath(tmp) %>">Last Response</A></B>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<TR VALIGN=TOP><TD ALIGN=LEFT COLSPAN=5><%= rdat.getStdFontTag(null,2) %> </FONT></TD></TR>
|
||||
<% Iterator it = data.getTopicIterator(); %>
|
||||
<% while (it.hasNext()) { %>
|
||||
<% TopicContext topic = (TopicContext)(it.next()); %>
|
||||
<%
|
||||
TopicContext topic = (TopicContext)(it.next());
|
||||
tmp = self + "&top=" + String.valueOf(topic.getTopicNumber()) + "&rnm=1";
|
||||
%>
|
||||
<TR VALIGN=TOP>
|
||||
<TD ALIGN=LEFT WIDTH="1%"><%= rdat.getStdFontTag(null,2) %>
|
||||
<A HREF="TODO"><%= topic.getTopicNumber() %></A>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>"><%= topic.getTopicNumber() %></A>
|
||||
</FONT></TD>
|
||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
||||
<A HREF="TODO"><%= topic.getName() %></A>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>"><%= topic.getName() %></A>
|
||||
<% if (topic.isArchived() && !(data.isView(ConferenceContext.DISPLAY_ARCHIVED))) { %>
|
||||
<EM>(archived)</EM>
|
||||
<% } else if (topic.isFrozen()) { %>
|
||||
<EM>(frozen)</EM>
|
||||
<% } // end if %>
|
||||
</FONT></TD>
|
||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||
<A HREF="TODO"><%= topic.getUnreadMessages() %></A>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>"><%= topic.getUnreadMessages() %></A>
|
||||
</FONT></TD>
|
||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||
<A HREF="TODO"><%= topic.getTotalMessages() %></A>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(self + "&top=" + String.valueOf(topic.getTopicNumber())
|
||||
+ "&p1=0&p2=-1") %>"><%= topic.getTotalMessages() %></A>
|
||||
</FONT></TD>
|
||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
||||
<A HREF="TODO"><%= rdat.formatDateForDisplay(topic.getLastUpdateDate()) %></A>
|
||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>"><%= rdat.formatDateForDisplay(topic.getLastUpdateDate()) %></A>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<% } // end while (more topics in enumeration) %>
|
||||
|
|
BIN
web/images/bn_archive_topic.gif
Normal file
After Width: | Height: | Size: 979 B |
BIN
web/images/bn_delete_topic.gif
Normal file
After Width: | Height: | Size: 969 B |
BIN
web/images/bn_freeze_topic.gif
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
web/images/bn_go.gif
Normal file
After Width: | Height: | Size: 879 B |
BIN
web/images/bn_hide.gif
Normal file
After Width: | Height: | Size: 906 B |
BIN
web/images/bn_hide_topic.gif
Normal file
After Width: | Height: | Size: 969 B |
BIN
web/images/bn_next_keep_new.gif
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
web/images/bn_next_topic.gif
Normal file
After Width: | Height: | Size: 951 B |
BIN
web/images/bn_nuke.gif
Normal file
After Width: | Height: | Size: 910 B |
BIN
web/images/bn_post_go_next.gif
Normal file
After Width: | Height: | Size: 997 B |
BIN
web/images/bn_post_reload.gif
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
web/images/bn_scribble.gif
Normal file
After Width: | Height: | Size: 949 B |
BIN
web/images/bn_show.gif
Normal file
After Width: | Height: | Size: 917 B |
BIN
web/images/bn_show_topic.gif
Normal file
After Width: | Height: | Size: 980 B |
BIN
web/images/bn_topic_list.gif
Normal file
After Width: | Height: | Size: 950 B |
BIN
web/images/bn_unarchive_topic.gif
Normal file
After Width: | Height: | Size: 1004 B |
BIN
web/images/bn_unfreeze_topic.gif
Normal file
After Width: | Height: | Size: 1015 B |