* 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>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>Conferencing/other functionality available via XML-RPC or SOAP calls</LI>
|
||||||
<LI>News page creation (see Slash, Squishdot, Scoop)</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>User diary pages (see Advogato, Kuro5hin)</LI>
|
||||||
<LI>Moderated discussions (see Slash, Scoop)</LI>
|
<LI>Moderated discussions (see Slash, Scoop)</LI>
|
||||||
<LI>Collaborative database facility (see Wiki, Everything2)</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
|
eminds
|
||||||
|
entil'zha
|
||||||
|
eps
|
||||||
erbo
|
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
|
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
|
snarf
|
||||||
snarfage
|
snarfage
|
||||||
|
snazzy
|
||||||
|
sourceforge
|
||||||
|
spaceport
|
||||||
|
spellchecker
|
||||||
|
spellchucker
|
||||||
|
spelunker
|
||||||
|
spelunkers
|
||||||
|
st
|
||||||
|
starbase
|
||||||
|
starfleet
|
||||||
|
starship
|
||||||
|
straightening
|
||||||
|
stunted
|
||||||
|
terrence
|
||||||
|
they're
|
||||||
|
turbolift
|
||||||
|
tuzanor
|
||||||
|
umbilical
|
||||||
|
umbilicals
|
||||||
|
url
|
||||||
utne
|
utne
|
||||||
|
valen
|
||||||
|
veni
|
||||||
|
we'll
|
||||||
|
we're
|
||||||
webb
|
webb
|
||||||
webbme
|
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-class>com.silverwrist.venice.servlets.ConfDisplay</servlet-class>
|
||||||
</servlet>
|
</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 -->
|
<!-- the following are test servlets, they should go away -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
|
@ -200,6 +208,11 @@
|
||||||
<url-pattern>/confdisp</url-pattern>
|
<url-pattern>/confdisp</url-pattern>
|
||||||
</servlet-mapping>
|
</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 -->
|
<!-- the following are test servlets, they should go away -->
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>testformdata</servlet-name>
|
<servlet-name>testformdata</servlet-name>
|
||||||
|
|
|
@ -416,6 +416,10 @@ INSERT INTO refaudit (type, descr) VALUES
|
||||||
(307, 'Delete Topic'),
|
(307, 'Delete Topic'),
|
||||||
(308, 'Set Topic Frozen'),
|
(308, 'Set Topic Frozen'),
|
||||||
(309, 'Set Topic Archive'),
|
(309, 'Set Topic Archive'),
|
||||||
|
(310, 'Post Message'),
|
||||||
|
(311, 'Hide Message'),
|
||||||
|
(312, 'Scribble Message'),
|
||||||
|
(313, 'Nuke Message'),
|
||||||
(9999999, 'DUMMY');
|
(9999999, 'DUMMY');
|
||||||
|
|
||||||
# The ISO 3166 two-letter country codes. Source is
|
# The ISO 3166 two-letter country codes. Source is
|
||||||
|
|
|
@ -64,4 +64,9 @@ public interface TopicContext
|
||||||
|
|
||||||
public abstract void fixSeen() throws DataException;
|
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
|
} // 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;
|
package com.silverwrist.venice.core.impl;
|
||||||
|
|
||||||
import java.sql.*;
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import com.silverwrist.venice.core.DataException;
|
||||||
|
|
||||||
public interface ConferenceBackend extends SIGBackend
|
public interface ConferenceBackend extends SIGBackend
|
||||||
{
|
{
|
||||||
|
@ -32,4 +34,14 @@ public interface ConferenceBackend extends SIGBackend
|
||||||
|
|
||||||
public abstract String realConfAlias();
|
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
|
} // end interface ConferenceBackend
|
||||||
|
|
|
@ -932,6 +932,37 @@ class ConferenceCoreData implements ConferenceData
|
||||||
|
|
||||||
} // end createNewTopic
|
} // 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)
|
* External static operations (usable only from within package)
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package com.silverwrist.venice.core.impl;
|
package com.silverwrist.venice.core.impl;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.silverwrist.venice.core.DataException;
|
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,
|
public abstract ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
|
||||||
int body_lines) throws DataException;
|
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
|
} // end interface ConferenceData
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package com.silverwrist.venice.core.impl;
|
package com.silverwrist.venice.core.impl;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.silverwrist.venice.core.DataException;
|
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,
|
public abstract ReturnTopicInfo createNewTopic(SIGBackend sig, String title, String pseud, String body,
|
||||||
int body_lines) throws DataException;
|
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
|
} // end interface ConferenceSIGContext
|
||||||
|
|
|
@ -618,4 +618,34 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
|
||||||
|
|
||||||
} // end createNewTopic
|
} // 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
|
} // end class ConferenceSIGContextImpl
|
||||||
|
|
|
@ -1047,6 +1047,42 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
|
|
||||||
} // end realConfAlias
|
} // 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
|
* 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 java.util.*;
|
||||||
import org.apache.log4j.*;
|
import org.apache.log4j.*;
|
||||||
import com.silverwrist.venice.db.*;
|
import com.silverwrist.venice.db.*;
|
||||||
|
import com.silverwrist.venice.htmlcheck.*;
|
||||||
import com.silverwrist.venice.security.AuditRecord;
|
import com.silverwrist.venice.security.AuditRecord;
|
||||||
import com.silverwrist.venice.core.*;
|
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
|
private static ResultSet queryByTopic(Statement stmt, int topicid, int uid) throws SQLException
|
||||||
{
|
{
|
||||||
StringBuffer sql =
|
StringBuffer sql =
|
||||||
new StringBuffer("SELECT t.topicid, t.num, t.creator_uid, t.top_message, t.frozen, t.archived, "
|
new StringBuffer("SELECT topics.topicid, topics.num, topics.creator_uid, topics.top_message, "
|
||||||
+ "t.createdate, t.lastupdate, t.name, IFNULL(s.hidden,0) AS hidden, "
|
+ "topics.frozen, topics.archived, topics.createdate, topics.lastupdate, "
|
||||||
+ "(t.top_message - IFNULL(s.last_message,-1)) AS unread FROM topics t "
|
+ "topics.name, IFNULL(topicsettings.hidden,0) AS hidden, "
|
||||||
+ "LEFT JOIN topicsettings s ON t.topicid = s.topicid AND s.uid = ");
|
+ "(topics.top_message - IFNULL(topicsettings.last_message,-1)) AS unread "
|
||||||
sql.append(uid).append(" WHERE t.topicid = ").append(topicid).append(';');
|
+ "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())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("SQL: " + sql.toString());
|
logger.debug("SQL: " + sql.toString());
|
||||||
return stmt.executeQuery(sql.toString());
|
return stmt.executeQuery(sql.toString());
|
||||||
|
@ -134,8 +137,29 @@ class TopicUserContextImpl implements TopicContext
|
||||||
|
|
||||||
} // end if
|
} // 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
|
try
|
||||||
{ // get a database connection
|
{ // get a database connection
|
||||||
conn = datapool.getConnection();
|
conn = datapool.getConnection();
|
||||||
Statement stmt = conn.createStatement();
|
refresh(conn);
|
||||||
|
|
||||||
// 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 try
|
} // end try
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
|
@ -524,8 +533,8 @@ class TopicUserContextImpl implements TopicContext
|
||||||
} // end try
|
} // end try
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
{ // turn SQLException into data exception
|
{ // turn SQLException into data exception
|
||||||
logger.error("DB error setting topic data: " + e.getMessage(),e);
|
logger.error("DB error setting topic user data: " + e.getMessage(),e);
|
||||||
throw new DataException("unable to set topic hidden status: " + e.getMessage(),e);
|
throw new DataException("unable to set unread messages: " + e.getMessage(),e);
|
||||||
|
|
||||||
} // end catch
|
} // end catch
|
||||||
finally
|
finally
|
||||||
|
@ -543,6 +552,213 @@ class TopicUserContextImpl implements TopicContext
|
||||||
|
|
||||||
} // end fixSeen
|
} // 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
|
* External operations usable only from within the package
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
|
|
@ -25,7 +25,7 @@ class DictNode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private static final int[] permute_tab =
|
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
|
* Attributes
|
||||||
|
@ -53,6 +53,8 @@ class DictNode
|
||||||
{
|
{
|
||||||
if (ltr=='-')
|
if (ltr=='-')
|
||||||
return 0;
|
return 0;
|
||||||
|
else if (ltr=='\'')
|
||||||
|
return 1;
|
||||||
else
|
else
|
||||||
return permute_tab[ltr - 'a'];
|
return permute_tab[ltr - 'a'];
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,62 @@ public class TreeLexicon implements ModSpellingDictionary
|
||||||
|
|
||||||
} // end constructor
|
} // 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
|
* Implementations from interface SpellingDictionary
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
@ -54,20 +110,22 @@ public class TreeLexicon implements ModSpellingDictionary
|
||||||
|
|
||||||
public synchronized boolean checkWord(String word)
|
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();
|
String real_word = word.toLowerCase();
|
||||||
DictNode cur = root;
|
if (checkSimple(real_word))
|
||||||
for (int i=0; i<real_word.length(); i++)
|
return true; // word is in lexicon - we're OK to go
|
||||||
{ // 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;
|
|
||||||
|
|
||||||
} // 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
|
} // end checkWord
|
||||||
|
|
||||||
|
@ -83,7 +141,7 @@ public class TreeLexicon implements ModSpellingDictionary
|
||||||
for (int i=0; i<real_word.length(); i++)
|
for (int i=0; i<real_word.length(); i++)
|
||||||
{ // move through the word - bail out if bogus chars
|
{ // move through the word - bail out if bogus chars
|
||||||
char ch = real_word.charAt(i);
|
char ch = real_word.charAt(i);
|
||||||
if (((ch<'a') || (ch>'z')) && (ch!='-'))
|
if (((ch<'a') || (ch>'z')) && (ch!='-') && (ch!='\''))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// advance down through trie
|
// 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_PAREN = 4;
|
||||||
private static final short ST_TAGQUOTE = 5;
|
private static final short ST_TAGQUOTE = 5;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------
|
||||||
|
* Internal constants
|
||||||
|
*--------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static final int MARGIN_SLOP = 5;
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------
|
||||||
* Attributes
|
* Attributes
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
@ -127,17 +134,17 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
||||||
|
|
||||||
private static final boolean isWordChar(char ch)
|
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
|
} // 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;
|
int l = 1;
|
||||||
while (l<buf.length())
|
while ((start+l)<buf.length())
|
||||||
{ // see if there's a break from word characters to non-word characters
|
{ // see if there's a break from word characters to non-word characters, or vice versa
|
||||||
if (isWordChar(buf.charAt(l))!=word_char)
|
if (isWordChar(buf.charAt(start+l))!=word_char)
|
||||||
break;
|
break;
|
||||||
l++;
|
l++;
|
||||||
|
|
||||||
|
@ -145,7 +152,13 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
||||||
|
|
||||||
return l;
|
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)
|
private void copyRewriters(Vector dest, List source)
|
||||||
{
|
{
|
||||||
|
@ -343,6 +356,7 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
||||||
{ // calculate where the next line break is
|
{ // calculate where the next line break is
|
||||||
int line_break = temp_buffer.toString().indexOf('\n');
|
int line_break = temp_buffer.toString().indexOf('\n');
|
||||||
int output_len = line_break;
|
int output_len = line_break;
|
||||||
|
boolean force_line_break = false;
|
||||||
if (output_len<0)
|
if (output_len<0)
|
||||||
output_len = temp_buffer.length();
|
output_len = temp_buffer.length();
|
||||||
|
|
||||||
|
@ -351,6 +365,8 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
||||||
int remain_space = (int)(config.getWordWrapLength() - columns);
|
int remain_space = (int)(config.getWordWrapLength() - columns);
|
||||||
if (remain_space<output_len)
|
if (remain_space<output_len)
|
||||||
output_len = remain_space;
|
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
|
} // end if
|
||||||
|
|
||||||
|
@ -366,9 +382,14 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
||||||
temp_buffer.setLength(0);
|
temp_buffer.setLength(0);
|
||||||
|
|
||||||
} // end if
|
} // 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);
|
temp_buffer.setLength(0);
|
||||||
|
|
||||||
|
} // end else
|
||||||
|
|
||||||
} // end while (still data in temp buffer)
|
} // end while (still data in temp buffer)
|
||||||
|
|
||||||
} // end doFlushWhitespace
|
} // end doFlushWhitespace
|
||||||
|
@ -418,23 +439,25 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
|
|
||||||
|
boolean first = true;
|
||||||
while (temp_buffer.length()>0)
|
while (temp_buffer.length()>0)
|
||||||
{ // find the length of the initial string of word or non-word characters
|
{ // find the length of the initial string of word or non-word characters
|
||||||
int sublen = getRunLength(temp_buffer);
|
int sublen = getRunLength(temp_buffer);
|
||||||
|
|
||||||
if (isWordChar(temp_buffer.charAt(0)))
|
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;
|
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++;
|
hyph_count++;
|
||||||
emitFromStartOfTempBuffer(hyph_count);
|
emitFromStartOfTempBuffer(hyph_count);
|
||||||
sublen -= 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;
|
int word_len = sublen;
|
||||||
hyph_count = 0;
|
hyph_count = 0;
|
||||||
while ((word_len>0) && (temp_buffer.charAt(word_len-1)=='-'))
|
while ((word_len>0) && (hyph_apos.indexOf(temp_buffer.charAt(word_len-1))>=0))
|
||||||
{ // decrement word length, increment hyphen count
|
{ // decrement word length, increment hyphen/apostrophe count
|
||||||
hyph_count++;
|
hyph_count++;
|
||||||
word_len--;
|
word_len--;
|
||||||
|
|
||||||
|
@ -458,13 +481,39 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
|
|
||||||
// now emit the rest of the hyphens
|
// now emit the rest of the hyphens/apostrophes
|
||||||
emitFromStartOfTempBuffer(hyph_count);
|
emitFromStartOfTempBuffer(hyph_count);
|
||||||
|
|
||||||
} // end if
|
} // 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);
|
emitFromStartOfTempBuffer(sublen);
|
||||||
|
|
||||||
|
} // end else
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
|
||||||
} // end while
|
} // end while
|
||||||
|
|
||||||
} // end doFlushString
|
} // end doFlushString
|
||||||
|
@ -884,7 +933,8 @@ class HTMLCheckerImpl implements HTMLChecker, HTMLCheckerBackend, RewriterServic
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
|
|
||||||
parse(str); // parse things
|
if (str!=null)
|
||||||
|
parse(str); // parse things
|
||||||
|
|
||||||
} // end append
|
} // end append
|
||||||
|
|
||||||
|
|
|
@ -54,5 +54,9 @@ public interface Audit
|
||||||
public static final int DELETE_TOPIC = 307;
|
public static final int DELETE_TOPIC = 307;
|
||||||
public static final int TOPIC_FREEZE = 308;
|
public static final int TOPIC_FREEZE = 308;
|
||||||
public static final int TOPIC_ARCHIVE = 309;
|
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
|
} // end interface Audit
|
||||||
|
|
|
@ -29,6 +29,47 @@ import com.silverwrist.venice.servlets.format.*;
|
||||||
|
|
||||||
public class ConfDisplay extends VeniceServlet
|
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
|
* Static data members
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
@ -183,6 +224,106 @@ public class ConfDisplay extends VeniceServlet
|
||||||
|
|
||||||
} // end getViewSortDefaults
|
} // 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
|
* Overrides from class HttpServlet
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
@ -287,7 +428,39 @@ public class ConfDisplay extends VeniceServlet
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("MODE: display messages in topic");
|
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
|
} // end if
|
||||||
else
|
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
|
} // 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()
|
public String getConfName()
|
||||||
{
|
{
|
||||||
return conf.getName();
|
return conf.getName();
|
||||||
|
@ -118,6 +126,15 @@ public class TopicListing implements JSPRender
|
||||||
|
|
||||||
} // end canDoReadNew
|
} // 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()
|
public boolean canCreateTopic()
|
||||||
{
|
{
|
||||||
return conf.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);
|
TopicListing data = TopicListing.retrieve(request);
|
||||||
Variables.failIfNull(data);
|
Variables.failIfNull(data);
|
||||||
RenderData rdat = RenderConfig.createRenderData(application,request,response);
|
RenderData rdat = RenderConfig.createRenderData(application,request,response);
|
||||||
String self = "confdisp?sig=" + String.valueOf(data.getSIGID()) + "&conf="
|
String self = "confdisp?" + data.getLocator();
|
||||||
+ String.valueOf(data.getConfID());
|
|
||||||
String tmp;
|
String tmp;
|
||||||
%>
|
%>
|
||||||
<% if (rdat.useHTMLComments()) { %><!-- Topic list for conf #<%= data.getConfID() %> --><% } %>
|
<% 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
|
SRC="<%= rdat.getFullImagePath("bn_conference_list.gif") %>" ALT="Conference List" WIDTH=80 HEIGHT=24
|
||||||
BORDER=0></A>
|
BORDER=0></A>
|
||||||
<% if (data.canCreateTopic()) { %>
|
<% if (data.canCreateTopic()) { %>
|
||||||
<% tmp = "confops?sig=" + String.valueOf(data.getSIGID()) + "&conf="
|
<% tmp = rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=T"); %>
|
||||||
+ String.valueOf(data.getConfID()) + "&cmd=T"; %>
|
<A HREF="<%= tmp %>"><IMG SRC="<%= rdat.getFullImagePath("bn_add_topic.gif") %>" ALT="Add Topic"
|
||||||
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>"><IMG SRC="<%= rdat.getFullImagePath("bn_add_topic.gif") %>"
|
WIDTH=80 HEIGHT=24 BORDER=0></A>
|
||||||
ALT="Add Topic" WIDTH=80 HEIGHT=24 BORDER=0></A>
|
|
||||||
<% } // end if %>
|
<% } // end if %>
|
||||||
<% if (data.canDoReadNew()) { %>
|
<% if (data.canDoReadNew()) { %>
|
||||||
<A HREF="TODO"><IMG SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>"
|
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getNextLocator()) %>"><IMG
|
||||||
ALT="Read New" WIDTH=80 HEIGHT=24 BORDER=0></A>
|
SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>" ALT="Read New" WIDTH=80 HEIGHT=24
|
||||||
|
BORDER=0></A>
|
||||||
<% } // end if %>
|
<% } // end if %>
|
||||||
<A HREF="TODO"><IMG SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>"
|
<A HREF="TODO"><IMG SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>"
|
||||||
ALT="Manage" WIDTH=80 HEIGHT=24 BORDER=0></A>
|
ALT="Manage" WIDTH=80 HEIGHT=24 BORDER=0></A>
|
||||||
|
@ -59,52 +58,61 @@
|
||||||
<% tmp = self + "&sort="
|
<% tmp = self + "&sort="
|
||||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_NUMBER) ? -ConferenceContext.SORT_NUMBER
|
+ String.valueOf(data.isSort(ConferenceContext.SORT_NUMBER) ? -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>
|
</FONT></TD>
|
||||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
||||||
<% tmp = self + "&sort="
|
<% tmp = self + "&sort="
|
||||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_NAME) ? -ConferenceContext.SORT_NAME
|
+ String.valueOf(data.isSort(ConferenceContext.SORT_NAME) ? -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>
|
</FONT></TD>
|
||||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||||
<% tmp = self + "&sort="
|
<% tmp = self + "&sort="
|
||||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_UNREAD) ? -ConferenceContext.SORT_UNREAD
|
+ String.valueOf(data.isSort(ConferenceContext.SORT_UNREAD) ? -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>
|
</FONT></TD>
|
||||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||||
<% tmp = self + "&sort="
|
<% tmp = self + "&sort="
|
||||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_TOTAL) ? -ConferenceContext.SORT_TOTAL
|
+ String.valueOf(data.isSort(ConferenceContext.SORT_TOTAL) ? -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>
|
</FONT></TD>
|
||||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
||||||
<% tmp = self + "&sort="
|
<% tmp = self + "&sort="
|
||||||
+ String.valueOf(data.isSort(ConferenceContext.SORT_DATE) ? -ConferenceContext.SORT_DATE
|
+ String.valueOf(data.isSort(ConferenceContext.SORT_DATE) ? -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>
|
</FONT></TD>
|
||||||
</TR>
|
</TR>
|
||||||
<TR VALIGN=TOP><TD ALIGN=LEFT COLSPAN=5><%= rdat.getStdFontTag(null,2) %> </FONT></TD></TR>
|
<TR VALIGN=TOP><TD ALIGN=LEFT COLSPAN=5><%= rdat.getStdFontTag(null,2) %> </FONT></TD></TR>
|
||||||
<% Iterator it = data.getTopicIterator(); %>
|
<% Iterator it = data.getTopicIterator(); %>
|
||||||
<% while (it.hasNext()) { %>
|
<% 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>
|
<TR VALIGN=TOP>
|
||||||
<TD ALIGN=LEFT WIDTH="1%"><%= rdat.getStdFontTag(null,2) %>
|
<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>
|
</FONT></TD>
|
||||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
<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>
|
</FONT></TD>
|
||||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
||||||
<A HREF="TODO"><%= topic.getUnreadMessages() %></A>
|
<A HREF="<%= rdat.getEncodedServletPath(tmp) %>"><%= topic.getUnreadMessages() %></A>
|
||||||
</FONT></TD>
|
</FONT></TD>
|
||||||
<TD ALIGN=RIGHT><%= rdat.getStdFontTag(null,2) %>
|
<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>
|
</FONT></TD>
|
||||||
<TD ALIGN=LEFT><%= rdat.getStdFontTag(null,2) %>
|
<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>
|
</FONT></TD>
|
||||||
</TR>
|
</TR>
|
||||||
<% } // end while (more topics in enumeration) %>
|
<% } // 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 |