Implemented partial support for conference hotlists ("Add To Hotlist"
button, Conferences sidebox).
This commit is contained in:
parent
bda25d9aa2
commit
7b7e6be996
16
TODO
16
TODO
|
@ -12,6 +12,16 @@ Lots!
|
||||||
- There's no system admin functionality AT ALL. We need to have this stuff
|
- There's no system admin functionality AT ALL. We need to have this stuff
|
||||||
before we go live. (It plugs into the Administrative SIG features.)
|
before we go live. (It plugs into the Administrative SIG features.)
|
||||||
|
|
||||||
|
- Unimplemented functions on the Top page:
|
||||||
|
Manage SIG list (SIG sidebox)
|
||||||
|
Manage Conference Hotlist (Conference sidebox)
|
||||||
|
Customize Sideboxes
|
||||||
|
|
||||||
|
- The plan for the "main" part of the Top page is to let a sysadmin put
|
||||||
|
notices there by "publishing" selected conference messages to the front page.
|
||||||
|
We may include a welcome message up top to be displayed if the user's not
|
||||||
|
logged in.
|
||||||
|
|
||||||
- Implement quick e-mail from the user profile display (engine support and
|
- Implement quick e-mail from the user profile display (engine support and
|
||||||
UI).
|
UI).
|
||||||
|
|
||||||
|
@ -23,14 +33,12 @@ Lots!
|
||||||
|
|
||||||
- Slippage during posting is still untested.
|
- Slippage during posting is still untested.
|
||||||
|
|
||||||
- Functions still to do on conferencing "topics" page:
|
|
||||||
Add Conference To Hotlist
|
|
||||||
|
|
||||||
- We need a "manage" button at conference list level so we can use that to
|
- We need a "manage" button at conference list level so we can use that to
|
||||||
manage the ordering of conferences. This operation should be accessible
|
manage the ordering of conferences. This operation should be accessible
|
||||||
only to users with "create" privilege on the SIG.
|
only to users with "create" privilege on the SIG.
|
||||||
|
|
||||||
- Implement conference hotlist for users.
|
- Conference hotlist is now partially implemented, but we need some more work
|
||||||
|
at engine level.
|
||||||
|
|
||||||
- Not everybody likes purple. Provide a way to change the default colors.
|
- Not everybody likes purple. Provide a way to change the default colors.
|
||||||
Probably via entries in render-config.xml. Of course, if we go to a
|
Probably via entries in render-config.xml. Of course, if we go to a
|
||||||
|
|
BIN
doc/tag_new.png
BIN
doc/tag_new.png
Binary file not shown.
Before Width: | Height: | Size: 685 B |
|
@ -1325,6 +1325,8 @@ INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcod
|
||||||
# new users.
|
# new users.
|
||||||
INSERT INTO sideboxes (uid, boxid, sequence, param)
|
INSERT INTO sideboxes (uid, boxid, sequence, param)
|
||||||
VALUES (1, 1, 100, NULL), (1, 2, 200, NULL);
|
VALUES (1, 1, 100, NULL), (1, 2, 200, NULL);
|
||||||
|
INSERT INTO confhotlist (uid, sequence, sigid, confid)
|
||||||
|
VALUES (1, 100, 2, 2);
|
||||||
|
|
||||||
# Add the 'Administrator' user to the users table.
|
# Add the 'Administrator' user to the users table.
|
||||||
# (UID = 2, CONTACTID = 2)
|
# (UID = 2, CONTACTID = 2)
|
||||||
|
@ -1337,6 +1339,8 @@ INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcod
|
||||||
# Create the default view for Administrator.
|
# Create the default view for Administrator.
|
||||||
INSERT INTO sideboxes (uid, boxid, sequence, param)
|
INSERT INTO sideboxes (uid, boxid, sequence, param)
|
||||||
VALUES (2, 1, 100, NULL), (2, 2, 200, NULL);
|
VALUES (2, 1, 100, NULL), (2, 2, 200, NULL);
|
||||||
|
INSERT INTO confhotlist (uid, sequence, sigid, confid)
|
||||||
|
VALUES (2, 100, 2, 2);
|
||||||
|
|
||||||
# Add the administration SIG to the SIGs table.
|
# Add the administration SIG to the SIGs table.
|
||||||
# (SIGID = 1, CONTACTID = 3)
|
# (SIGID = 1, CONTACTID = 3)
|
||||||
|
@ -1432,6 +1436,8 @@ INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcod
|
||||||
VALUES (5, 'Test', 'User', 'Denver', 'CO', '80231', 'US', 'testuser@example.com', 3);
|
VALUES (5, 'Test', 'User', 'Denver', 'CO', '80231', 'US', 'testuser@example.com', 3);
|
||||||
INSERT INTO sideboxes (uid, boxid, sequence, param)
|
INSERT INTO sideboxes (uid, boxid, sequence, param)
|
||||||
VALUES (3, 1, 100, NULL), (3, 2, 200, NULL);
|
VALUES (3, 1, 100, NULL), (3, 2, 200, NULL);
|
||||||
|
INSERT INTO confhotlist (uid, sequence, sigid, confid)
|
||||||
|
VALUES (3, 100, 2, 2);
|
||||||
INSERT INTO sigmember (sigid, uid, granted_lvl, locked)
|
INSERT INTO sigmember (sigid, uid, granted_lvl, locked)
|
||||||
VALUES (2, 3, 6500, 1);
|
VALUES (2, 3, 6500, 1);
|
||||||
|
|
||||||
|
|
|
@ -141,4 +141,12 @@ public interface ConferenceContext
|
||||||
|
|
||||||
public abstract boolean canDeleteConference();
|
public abstract boolean canDeleteConference();
|
||||||
|
|
||||||
|
public abstract boolean isInHotlist();
|
||||||
|
|
||||||
|
public abstract void addToHotlist() throws DataException;
|
||||||
|
|
||||||
|
public abstract boolean canAddToHotlist();
|
||||||
|
|
||||||
|
public abstract SIGContext getEnclosingSIG();
|
||||||
|
|
||||||
} // end interface ConferenceContext
|
} // end interface ConferenceContext
|
||||||
|
|
26
src/com/silverwrist/venice/core/ConferenceHotlistEntry.java
Normal file
26
src/com/silverwrist/venice/core/ConferenceHotlistEntry.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||||
|
* (the "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||||
|
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||||
|
* language governing rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code is the Venice Web Communities System.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||||
|
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||||
|
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*/
|
||||||
|
package com.silverwrist.venice.core;
|
||||||
|
|
||||||
|
public interface ConferenceHotlistEntry
|
||||||
|
{
|
||||||
|
public abstract ConferenceContext getConference();
|
||||||
|
|
||||||
|
public abstract int getSequence();
|
||||||
|
|
||||||
|
} // end interface ConferenceHotlistEntry
|
|
@ -87,4 +87,6 @@ public interface UserContext extends SearchMode
|
||||||
|
|
||||||
public abstract List getSideBoxList() throws DataException;
|
public abstract List getSideBoxList() throws DataException;
|
||||||
|
|
||||||
|
public abstract List getConferenceHotlist() throws DataException;
|
||||||
|
|
||||||
} // end interface UserContext
|
} // end interface UserContext
|
||||||
|
|
|
@ -116,6 +116,37 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
|
|
||||||
} // end class FixSeenHelper
|
} // end class FixSeenHelper
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------------
|
||||||
|
* Static class used to return hot list entries
|
||||||
|
*--------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static class MyHotlist implements ConferenceHotlistEntry
|
||||||
|
{
|
||||||
|
private ConferenceContext conf;
|
||||||
|
private int seq;
|
||||||
|
|
||||||
|
MyHotlist(ConferenceContext conf, int seq)
|
||||||
|
{
|
||||||
|
this.conf = conf;
|
||||||
|
this.seq = seq;
|
||||||
|
|
||||||
|
} // end constructor
|
||||||
|
|
||||||
|
public ConferenceContext getConference()
|
||||||
|
{
|
||||||
|
return conf;
|
||||||
|
|
||||||
|
} // end getConference
|
||||||
|
|
||||||
|
public int getSequence()
|
||||||
|
{
|
||||||
|
return seq;
|
||||||
|
|
||||||
|
} // end getSequence
|
||||||
|
|
||||||
|
} // end class MyHotlist
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------
|
||||||
* Static data members
|
* Static data members
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
@ -515,8 +546,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
if (post>create)
|
if (post>create)
|
||||||
{ // Post level should be no greater than Create
|
{ // Post level should be no greater than Create
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Post level (" + String.valueOf(post) + ") was greater than create level ("
|
logger.debug("Post level (" + post + ") was greater than create level (" + create + "), correcting");
|
||||||
+ String.valueOf(create) + "), correcting");
|
|
||||||
post = create;
|
post = create;
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
|
@ -524,8 +554,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
if (read>post)
|
if (read>post)
|
||||||
{ // Read level should be no greater than Post
|
{ // Read level should be no greater than Post
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Read level (" + String.valueOf(read) + ") was greater than post level ("
|
logger.debug("Read level (" + read + ") was greater than post level (" + post + "), correcting");
|
||||||
+ String.valueOf(post) + "), correcting");
|
|
||||||
read = post;
|
read = post;
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
|
@ -533,8 +562,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
if (change>delete)
|
if (change>delete)
|
||||||
{ // Change level should be no greater than Delete
|
{ // Change level should be no greater than Delete
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Change level (" + String.valueOf(change) + ") was greater than delete level ("
|
logger.debug("Change level (" + change + ") was greater than delete level (" + delete
|
||||||
+ String.valueOf(delete) + "), correcting");
|
+ "), correcting");
|
||||||
change = delete;
|
change = delete;
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
|
@ -542,8 +571,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
if (nuke>delete)
|
if (nuke>delete)
|
||||||
{ // Nuke level should be no greater than Delete
|
{ // Nuke level should be no greater than Delete
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Nuke level (" + String.valueOf(nuke) + ") was greater than delete level ("
|
logger.debug("Nuke level (" + nuke + ") was greater than delete level (" + delete + "), correcting");
|
||||||
+ String.valueOf(delete) + "), correcting");
|
|
||||||
nuke = delete;
|
nuke = delete;
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
|
@ -551,8 +579,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
if (hide>nuke)
|
if (hide>nuke)
|
||||||
{ // Hide level should be no greater than Nuke
|
{ // Hide level should be no greater than Nuke
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Hide level (" + String.valueOf(hide) + ") was greater than nuke level ("
|
logger.debug("Hide level (" + hide + ") was greater than nuke level (" + nuke + "), correcting");
|
||||||
+ String.valueOf(nuke) + "), correcting");
|
|
||||||
hide = nuke;
|
hide = nuke;
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
|
@ -791,7 +818,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
|
|
||||||
public boolean anyUnread()
|
public boolean anyUnread()
|
||||||
{
|
{
|
||||||
if (deleted)
|
if (deleted || sig.userIsAnonymous())
|
||||||
return false;
|
return false;
|
||||||
Connection conn = null; // pooled database connection
|
Connection conn = null; // pooled database connection
|
||||||
|
|
||||||
|
@ -1228,6 +1255,110 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
|
|
||||||
} // end canDeleteConference
|
} // end canDeleteConference
|
||||||
|
|
||||||
|
public boolean isInHotlist()
|
||||||
|
{
|
||||||
|
Connection conn = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{ // retrieve a connection from the datapool
|
||||||
|
conn = datapool.getConnection();
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
|
||||||
|
// do a quickie query
|
||||||
|
StringBuffer sql = new StringBuffer("SELECT sequence FROM confhotlist WHERE uid = ");
|
||||||
|
sql.append(sig.realUID()).append(" AND sigid = ").append(sig.realSIGID()).append(" AND confid = ");
|
||||||
|
sql.append(confid).append(';');
|
||||||
|
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||||
|
return rs.next();
|
||||||
|
|
||||||
|
} // end try
|
||||||
|
catch (SQLException e)
|
||||||
|
{ // this becomes a DataException
|
||||||
|
logger.error("DB error checking hotlist: " + e.getMessage(),e);
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} // end catch
|
||||||
|
finally
|
||||||
|
{ // make sure we release the connection before we go
|
||||||
|
if (conn!=null)
|
||||||
|
datapool.releaseConnection(conn);
|
||||||
|
|
||||||
|
} // end finally
|
||||||
|
|
||||||
|
} // end isInHotlist
|
||||||
|
|
||||||
|
public void addToHotlist() throws DataException
|
||||||
|
{
|
||||||
|
Connection conn = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{ // retrieve a connection from the datapool
|
||||||
|
conn = datapool.getConnection();
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
|
||||||
|
stmt.executeUpdate("LOCK TABLES confhotlist WRITE;");
|
||||||
|
try
|
||||||
|
{ // do a quickie query to see if we're already in the hotlist
|
||||||
|
StringBuffer sql = new StringBuffer("SELECT sequence FROM confhotlist WHERE uid = ");
|
||||||
|
sql.append(sig.realUID()).append(" AND sigid = ").append(sig.realSIGID()).append(" AND confid = ");
|
||||||
|
sql.append(confid).append(';');
|
||||||
|
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||||
|
if (rs.next())
|
||||||
|
return; // already in hotlist - this is a no-op
|
||||||
|
|
||||||
|
// find a sequence number for the new entry
|
||||||
|
sql.setLength(0);
|
||||||
|
sql.append("SELECT MAX(sequence) FROM confhotlist WHERE uid = ").append(sig.realUID()).append(';');
|
||||||
|
rs = stmt.executeQuery(sql.toString());
|
||||||
|
if (!(rs.next()))
|
||||||
|
throw new InternalStateError("bogus query result on addToHotlist");
|
||||||
|
int new_sequence = rs.getInt(1) + 100;
|
||||||
|
|
||||||
|
// add the new record
|
||||||
|
sql.setLength(0);
|
||||||
|
sql.append("INSERT INTO confhotlist (uid, sequence, sigid, confid) VALUES (").append(sig.realUID());
|
||||||
|
sql.append(", ").append(new_sequence).append(", ").append(sig.realSIGID()).append(", ");
|
||||||
|
sql.append(confid).append(");");
|
||||||
|
stmt.executeUpdate(sql.toString());
|
||||||
|
|
||||||
|
} // end try
|
||||||
|
finally
|
||||||
|
{ // make sure the table is unlocked before we go
|
||||||
|
Statement ulk_stmt = conn.createStatement();
|
||||||
|
ulk_stmt.executeUpdate("UNLOCK TABLES;");
|
||||||
|
|
||||||
|
} // end finally
|
||||||
|
|
||||||
|
} // end try
|
||||||
|
catch (SQLException e)
|
||||||
|
{ // this becomes a DataException
|
||||||
|
logger.error("DB error adding to hotlist: " + e.getMessage(),e);
|
||||||
|
throw new DataException("error adding to hotlist: " + e.getMessage(),e);
|
||||||
|
|
||||||
|
} // end catch
|
||||||
|
finally
|
||||||
|
{ // make sure we release the connection before we go
|
||||||
|
if (conn!=null)
|
||||||
|
datapool.releaseConnection(conn);
|
||||||
|
|
||||||
|
} // end finally
|
||||||
|
|
||||||
|
} // end addToHotList
|
||||||
|
|
||||||
|
public boolean canAddToHotlist()
|
||||||
|
{
|
||||||
|
if (sig.userIsAnonymous())
|
||||||
|
return false;
|
||||||
|
return !(isInHotlist());
|
||||||
|
|
||||||
|
} // end canAddToHotlist
|
||||||
|
|
||||||
|
public SIGContext getEnclosingSIG()
|
||||||
|
{
|
||||||
|
return sig.selfSIG();
|
||||||
|
|
||||||
|
} // end getEnclosingSIG
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------
|
||||||
* Implementations from interface UserBackend
|
* Implementations from interface UserBackend
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
@ -1268,6 +1399,12 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
public SIGContext selfSIG()
|
||||||
|
{
|
||||||
|
return sig.selfSIG();
|
||||||
|
|
||||||
|
} // end selfsig;
|
||||||
|
|
||||||
public int realSIGID()
|
public int realSIGID()
|
||||||
{
|
{
|
||||||
return sig.realSIGID();
|
return sig.realSIGID();
|
||||||
|
@ -1468,8 +1605,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
static List getSIGConferences(EngineBackend engine, SIGBackend sig, DataPool datapool) throws DataException
|
static List getSIGConferences(EngineBackend engine, SIGBackend sig, DataPool datapool) throws DataException
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("getSIGConferences for SIG # " + String.valueOf(sig.realSIGID()) + ", user #"
|
logger.debug("getSIGConferences for SIG # " + sig.realSIGID() + ", user #" + sig.realUID());
|
||||||
+ String.valueOf(sig.realUID()));
|
|
||||||
Vector rc = new Vector(); // return from this function
|
Vector rc = new Vector(); // return from this function
|
||||||
Connection conn = null; // pooled database connection
|
Connection conn = null; // pooled database connection
|
||||||
|
|
||||||
|
@ -1529,8 +1665,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
int confid) throws DataException
|
int confid) throws DataException
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("getConference(#" + String.valueOf(confid) + ") for SIG # "
|
logger.debug("getConference(#" + confid + ") for SIG # " + sig.realSIGID() + ", user #" + sig.realUID());
|
||||||
+ String.valueOf(sig.realSIGID()) + ", user #" + String.valueOf(sig.realUID()));
|
|
||||||
|
|
||||||
Connection conn = null; // pooled database connection
|
Connection conn = null; // pooled database connection
|
||||||
|
|
||||||
|
@ -1553,8 +1688,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
// Run that monster query!
|
// Run that monster query!
|
||||||
ResultSet rs = stmt.executeQuery(sql.toString());
|
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||||
if (!(rs.next()))
|
if (!(rs.next()))
|
||||||
throw new DataException("conference ID#" + String.valueOf(confid) + " not found in SIG#"
|
throw new DataException("conference ID#" + confid + " not found in SIG#" + sig.realSIGID());
|
||||||
+ String.valueOf(sig.realSIGID()));
|
|
||||||
|
|
||||||
// pass back the new object
|
// pass back the new object
|
||||||
return new ConferenceUserContextImpl(engine,sig,datapool,confid,rs.getString(2),
|
return new ConferenceUserContextImpl(engine,sig,datapool,confid,rs.getString(2),
|
||||||
|
@ -1581,8 +1715,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
String alias) throws DataException
|
String alias) throws DataException
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("getConference(\"" + alias + "\") for SIG # " + String.valueOf(sig.realSIGID())
|
logger.debug("getConference(\"" + alias + "\") for SIG # " + sig.realSIGID() + ", user #"
|
||||||
+ ", user #" + String.valueOf(sig.realUID()));
|
+ sig.realUID());
|
||||||
|
|
||||||
Connection conn = null; // pooled database connection
|
Connection conn = null; // pooled database connection
|
||||||
|
|
||||||
|
@ -1607,8 +1741,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
// Run that monster query!
|
// Run that monster query!
|
||||||
ResultSet rs = stmt.executeQuery(sql.toString());
|
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||||
if (!(rs.next()))
|
if (!(rs.next()))
|
||||||
throw new DataException("conference \"" + alias + "\" not found in SIG#"
|
throw new DataException("conference \"" + alias + "\" not found in SIG#" + sig.realSIGID());
|
||||||
+ String.valueOf(sig.realSIGID()));
|
|
||||||
|
|
||||||
// pass back the new object
|
// pass back the new object
|
||||||
return new ConferenceUserContextImpl(engine,sig,datapool,rs.getInt(1),rs.getString(3),rs.getString(4),
|
return new ConferenceUserContextImpl(engine,sig,datapool,rs.getInt(1),rs.getString(3),rs.getString(4),
|
||||||
|
@ -1630,4 +1763,77 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
|
|
||||||
} // end getConference
|
} // end getConference
|
||||||
|
|
||||||
|
static List getUserHotlist(EngineBackend engine, UserBackend user, DataPool datapool) throws DataException
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("getUserHotlist for user #" + user.realUID());
|
||||||
|
|
||||||
|
Connection conn = null; // pooled database connection
|
||||||
|
Vector rc = new Vector(); // return from this function
|
||||||
|
|
||||||
|
try
|
||||||
|
{ // get a database connection
|
||||||
|
conn = datapool.getConnection();
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
|
||||||
|
// Build a monster query! We pull the SIGID and ConfID entries from the confhotlist table,
|
||||||
|
// but we need to pull in "confs" and "confmember" (left joined) to get enough data to create
|
||||||
|
// a ConferenceUserContextImpl object.
|
||||||
|
StringBuffer sql =
|
||||||
|
new StringBuffer("SELECT h.sigid, h.confid, c.name, c.descr, c.createdate, s.granted_lvl, "
|
||||||
|
+ "f.granted_lvl, h.sequence FROM confhotlist h, sigtoconf s, confs c "
|
||||||
|
+ "LEFT JOIN confmember f ON h.confid = f.confid AND h.uid = f.uid "
|
||||||
|
+ "WHERE h.confid = s.confid AND c.confid = h.confid AND h.uid = ");
|
||||||
|
sql.append(user.realUID()).append(" ORDER BY h.sequence ASC;");
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("SQL: " + sql.toString());
|
||||||
|
|
||||||
|
// Run that puppy!
|
||||||
|
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||||
|
|
||||||
|
// Create some temporary data structures to assist us in building the return list.
|
||||||
|
HashMap sig_backend_cache = new HashMap();
|
||||||
|
|
||||||
|
while (rs.next())
|
||||||
|
{ // retrieve the sigid from the resultset first
|
||||||
|
Integer sigid = new Integer(rs.getInt(1));
|
||||||
|
|
||||||
|
// we need a SIG backend for our conference, so make sure we have one
|
||||||
|
SIGBackend sig = (SIGBackend)(sig_backend_cache.get(sigid));
|
||||||
|
if (sig==null)
|
||||||
|
{ // get it and make sure it's in the cache for next time
|
||||||
|
sig = SIGUserContextImpl.getSIGBackend(engine,user,datapool,conn,sigid.intValue());
|
||||||
|
sig_backend_cache.put(sigid,sig);
|
||||||
|
|
||||||
|
} // end if
|
||||||
|
|
||||||
|
// make the new ConferenceContext
|
||||||
|
ConferenceContext conf =
|
||||||
|
new ConferenceUserContextImpl(engine,sig,datapool,rs.getInt(2),rs.getString(3),rs.getString(4),
|
||||||
|
SQLUtil.getFullDateTime(rs,5),rs.getInt(6),rs.getInt(7),conn);
|
||||||
|
|
||||||
|
// and create the actual return value
|
||||||
|
ConferenceHotlistEntry hle = new MyHotlist(conf,rs.getInt(8));
|
||||||
|
rc.add(hle);
|
||||||
|
|
||||||
|
} // end while
|
||||||
|
|
||||||
|
} // end try
|
||||||
|
catch (SQLException e)
|
||||||
|
{ // turn SQLException into data exception
|
||||||
|
logger.error("DB error reading hotlist entries: " + e.getMessage(),e);
|
||||||
|
throw new DataException("unable to retrieve hotlist information: " + 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);
|
||||||
|
|
||||||
|
} // end getUserHotlist
|
||||||
|
|
||||||
} // end class ConferenceUserContextImpl
|
} // end class ConferenceUserContextImpl
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||||
* language governing rights and limitations under the License.
|
* language governing rights and limitations under the License.
|
||||||
*
|
*
|
||||||
* The Original Code is the Venice Web Community System.
|
* The Original Code is the Venice Web Communities System.
|
||||||
*
|
*
|
||||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
* 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
|
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||||
|
@ -18,9 +18,12 @@
|
||||||
package com.silverwrist.venice.core.impl;
|
package com.silverwrist.venice.core.impl;
|
||||||
|
|
||||||
import com.silverwrist.venice.core.DataException;
|
import com.silverwrist.venice.core.DataException;
|
||||||
|
import com.silverwrist.venice.core.SIGContext;
|
||||||
|
|
||||||
public interface SIGBackend extends UserBackend
|
public interface SIGBackend extends UserBackend
|
||||||
{
|
{
|
||||||
|
public abstract SIGContext selfSIG();
|
||||||
|
|
||||||
public abstract int realSIGID();
|
public abstract int realSIGID();
|
||||||
|
|
||||||
public abstract boolean userHideHiddenConferences();
|
public abstract boolean userHideHiddenConferences();
|
||||||
|
|
|
@ -229,6 +229,38 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
|
||||||
|
|
||||||
} // end testConferenceAccess
|
} // end testConferenceAccess
|
||||||
|
|
||||||
|
private static SIGUserContextImpl getSIGPrivate(EngineBackend engine, UserBackend user, DataPool datapool,
|
||||||
|
Connection conn, int sigid) throws DataException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{ // create the query to find the SIG in the table
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
StringBuffer sql = new StringBuffer("SELECT signame, alias FROM sigs WHERE sigid = ");
|
||||||
|
sql.append(sigid).append(';');
|
||||||
|
ResultSet rs = stmt.executeQuery(sql.toString());
|
||||||
|
if (!(rs.next()))
|
||||||
|
{ // the SIG entry was not found
|
||||||
|
logger.error("SIG " + String.valueOf(sigid) + " not found in database");
|
||||||
|
throw new DataException("SIG #" + String.valueOf(sigid) + " was not found in the database.");
|
||||||
|
|
||||||
|
} // end if
|
||||||
|
|
||||||
|
// initialize the object and check membership info
|
||||||
|
SIGUserContextImpl sc = new SIGUserContextImpl(engine,user,datapool,sigid,rs.getString("signame"),
|
||||||
|
rs.getString("alias"));
|
||||||
|
sc.checkMembership(conn);
|
||||||
|
return sc;
|
||||||
|
|
||||||
|
} // end try
|
||||||
|
catch (SQLException e)
|
||||||
|
{ // turn SQLException into data exception
|
||||||
|
logger.error("DB error reading SIG entry: " + e.getMessage(),e);
|
||||||
|
throw new DataException("unable to retrieve SIG information: " + e.getMessage(),e);
|
||||||
|
|
||||||
|
} // end catch
|
||||||
|
|
||||||
|
} // end getSIGPrivate
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------
|
||||||
* Implementations from class SIGContext
|
* Implementations from class SIGContext
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
@ -1132,6 +1164,12 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
public SIGContext selfSIG()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
|
||||||
|
} // end selfsig;
|
||||||
|
|
||||||
public int realSIGID()
|
public int realSIGID()
|
||||||
{
|
{
|
||||||
return sigid;
|
return sigid;
|
||||||
|
@ -1248,23 +1286,8 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
|
||||||
{ // get a database connection
|
{ // get a database connection
|
||||||
conn = datapool.getConnection();
|
conn = datapool.getConnection();
|
||||||
|
|
||||||
// create the query to find the SIG in the table
|
// return the SIG we want
|
||||||
Statement stmt = conn.createStatement();
|
return getSIGPrivate(engine,user,datapool,conn,sigid);
|
||||||
StringBuffer sql = new StringBuffer("SELECT signame, alias FROM sigs WHERE sigid = ");
|
|
||||||
sql.append(sigid).append(';');
|
|
||||||
ResultSet rs = stmt.executeQuery(sql.toString());
|
|
||||||
if (!(rs.next()))
|
|
||||||
{ // the SIG entry was not found
|
|
||||||
logger.error("SIG " + String.valueOf(sigid) + " not found in database");
|
|
||||||
throw new DataException("SIG #" + String.valueOf(sigid) + " was not found in the database.");
|
|
||||||
|
|
||||||
} // end if
|
|
||||||
|
|
||||||
// initialize the object and check membership info
|
|
||||||
SIGUserContextImpl sc = new SIGUserContextImpl(engine,user,datapool,sigid,rs.getString("signame"),
|
|
||||||
rs.getString("alias"));
|
|
||||||
sc.checkMembership(conn);
|
|
||||||
return sc;
|
|
||||||
|
|
||||||
} // end try
|
} // end try
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
|
@ -1325,6 +1348,13 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
|
||||||
|
|
||||||
} // end getSIGContext
|
} // end getSIGContext
|
||||||
|
|
||||||
|
static SIGBackend getSIGBackend(EngineBackend engine, UserBackend user, DataPool datapool, Connection conn,
|
||||||
|
int sigid) throws DataException
|
||||||
|
{
|
||||||
|
return getSIGPrivate(engine,user,datapool,conn,sigid);
|
||||||
|
|
||||||
|
} // end getSIGBackend
|
||||||
|
|
||||||
static List searchForSIGs(EngineBackend engine, UserBackend user, DataPool datapool, int field,
|
static List searchForSIGs(EngineBackend engine, UserBackend user, DataPool datapool, int field,
|
||||||
int mode, String term, int offset, int count) throws DataException
|
int mode, String term, int offset, int count) throws DataException
|
||||||
{
|
{
|
||||||
|
|
|
@ -862,6 +862,12 @@ class UserContextImpl implements UserContext, UserBackend
|
||||||
|
|
||||||
} // end getSideBoxList
|
} // end getSideBoxList
|
||||||
|
|
||||||
|
public List getConferenceHotlist() throws DataException
|
||||||
|
{
|
||||||
|
return ConferenceUserContextImpl.getUserHotlist(engine,this,datapool);
|
||||||
|
|
||||||
|
} // end getConferenceHotlist
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------
|
||||||
* Implementations from interface UserBackend
|
* Implementations from interface UserBackend
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
|
|
@ -874,7 +874,8 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
|
||||||
{ // look to see if the user name is already present
|
{ // look to see if the user name is already present
|
||||||
conn = datapool.getConnection();
|
conn = datapool.getConnection();
|
||||||
Statement stmt = conn.createStatement();
|
Statement stmt = conn.createStatement();
|
||||||
stmt.executeUpdate("LOCK TABLES users WRITE, userprefs WRITE, sigmember WRITE, sideboxes WRITE;");
|
stmt.executeUpdate("LOCK TABLES users WRITE, userprefs WRITE, sigmember WRITE, sideboxes WRITE, "
|
||||||
|
+ "confhotlist WRITE;");
|
||||||
try
|
try
|
||||||
{ // make sure the user name isn't there already
|
{ // make sure the user name isn't there already
|
||||||
ResultSet rs = stmt.executeQuery("SELECT uid FROM users WHERE username = '" + encode_username + "';");
|
ResultSet rs = stmt.executeQuery("SELECT uid FROM users WHERE username = '" + encode_username + "';");
|
||||||
|
@ -967,6 +968,31 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("...loaded default sidebox config");
|
logger.debug("...loaded default sidebox config");
|
||||||
|
|
||||||
|
// get the hotlist configuration for this user
|
||||||
|
rs = stmt.executeQuery("SELECT confhotlist.sequence, confhotlist.sigid, confhotlist.confid FROM "
|
||||||
|
+ "confhotlist, users WHERE confhotlist.uid = users.uid AND users.is_anon = 1;");
|
||||||
|
sql.setLength(0);
|
||||||
|
while (rs.next())
|
||||||
|
{ // set up to insert into the confhotlist table
|
||||||
|
if (sql.length()==0)
|
||||||
|
sql.append("INSERT INTO confhotlist (uid, sequence, sigid, confid) VALUES ");
|
||||||
|
else
|
||||||
|
sql.append(", ");
|
||||||
|
sql.append('(').append(new_uid).append(", ").append(rs.getInt(1)).append(", ").append(rs.getInt(2));
|
||||||
|
sql.append(", ").append(rs.getInt(3)).append(')');
|
||||||
|
|
||||||
|
} // end while
|
||||||
|
|
||||||
|
if (sql.length()>0)
|
||||||
|
{ // execute the big update
|
||||||
|
sql.append(';');
|
||||||
|
stmt.executeUpdate(sql.toString());
|
||||||
|
|
||||||
|
} // end if
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("...loaded default hotlist config");
|
||||||
|
|
||||||
} // end try
|
} // end try
|
||||||
finally
|
finally
|
||||||
{ // make sure the tables get unlocked before we go
|
{ // make sure the tables get unlocked before we go
|
||||||
|
|
|
@ -326,6 +326,28 @@ public class ConfOperations extends VeniceServlet
|
||||||
|
|
||||||
} // end if ("M" command)
|
} // end if ("M" command)
|
||||||
|
|
||||||
|
if (cmd.equals("H"))
|
||||||
|
{ // "H" = "Add Conference To Hotlist" (requires conference parameter)
|
||||||
|
ConferenceContext conf = getConferenceParameter(request,sig,true,on_error);
|
||||||
|
on_error = "confdisp?sig=" + sig.getSIGID() + "&conf=" + conf.getConfID();
|
||||||
|
|
||||||
|
try
|
||||||
|
{ // add to the hotlist
|
||||||
|
conf.addToHotlist();
|
||||||
|
|
||||||
|
// and trap back to the conference display
|
||||||
|
throw new RedirectResult(on_error);
|
||||||
|
|
||||||
|
} // end try
|
||||||
|
catch (DataException de)
|
||||||
|
{ // something wrong in the database
|
||||||
|
return new ErrorBox("Database Error","Database error adding to hotlist: " + de.getMessage(),
|
||||||
|
on_error);
|
||||||
|
|
||||||
|
} // end catch
|
||||||
|
|
||||||
|
} // end if ("H" command)
|
||||||
|
|
||||||
if (cmd.equals("DEL"))
|
if (cmd.equals("DEL"))
|
||||||
{ // "DEL" = "Delete Conference (requires conference parameter)
|
{ // "DEL" = "Delete Conference (requires conference parameter)
|
||||||
ConferenceContext conf = getConferenceParameter(request,sig,true,on_error);
|
ConferenceContext conf = getConferenceParameter(request,sig,true,on_error);
|
||||||
|
|
|
@ -19,6 +19,7 @@ package com.silverwrist.venice.servlets.format;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import com.silverwrist.util.StringUtil;
|
||||||
import com.silverwrist.venice.core.*;
|
import com.silverwrist.venice.core.*;
|
||||||
|
|
||||||
public class SideBoxConferences implements ContentRender
|
public class SideBoxConferences implements ContentRender
|
||||||
|
@ -29,15 +30,17 @@ public class SideBoxConferences implements ContentRender
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private UserContext uc;
|
private UserContext uc;
|
||||||
|
private List hotlist;
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------
|
||||||
* Constructor
|
* Constructor
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public SideBoxConferences(UserContext uc, String parameter)
|
public SideBoxConferences(UserContext uc, String parameter) throws DataException
|
||||||
{
|
{
|
||||||
this.uc = uc;
|
this.uc = uc;
|
||||||
|
this.hotlist = uc.getConferenceHotlist();
|
||||||
|
|
||||||
} // end constructor
|
} // end constructor
|
||||||
|
|
||||||
|
@ -62,14 +65,34 @@ public class SideBoxConferences implements ContentRender
|
||||||
|
|
||||||
public void renderHere(Writer out, RenderData rdat) throws IOException
|
public void renderHere(Writer out, RenderData rdat) throws IOException
|
||||||
{
|
{
|
||||||
/* BEGIN TEMP */
|
out.write(rdat.getStdFontTag(null,2) + "\n");
|
||||||
out.write("<FONT FACE=\"Arial, Helvetica\" SIZE=2><UL>\n");
|
if (hotlist.size()>0)
|
||||||
out.write("<LI>BOFH (Benevolent Dictators)</LI>\n");
|
{ // display the list of conferences
|
||||||
out.write("<LI>Playground (Electric Minds)</LI>\n");
|
out.write("<TABLE ALIGN=CENTER BORDER=0 CELLPADDING=0 CELLSPACING=2>\n");
|
||||||
out.write("<LI>Commons (Electric Minds)</LI>\n");
|
Iterator it = hotlist.iterator();
|
||||||
out.write("<LI>Top Ten Lists (Pamela's Lounge)</LI>\n");
|
while (it.hasNext())
|
||||||
out.write("</UL></FONT>\n");
|
{ // display the names of the conferences and SIGs one by one
|
||||||
/* END TEMP */
|
ConferenceHotlistEntry hle = (ConferenceHotlistEntry)(it.next());
|
||||||
|
ConferenceContext conf = hle.getConference();
|
||||||
|
String href = "confdisp?sig=" + conf.getEnclosingSIG().getSIGID() + "&conf=" + conf.getConfID();
|
||||||
|
out.write("<TR VALIGN=MIDDLE>\n<TD ALIGN=CENTER WIDTH=14><IMG SRC=\""
|
||||||
|
+ rdat.getFullImagePath("purple-ball.gif")
|
||||||
|
+ "\" ALT=\"*\" WIDTH=14 HEIGHT=14 BORDER=0></TD>\n");
|
||||||
|
out.write("<TD ALIGN=LEFT>\n" + rdat.getStdFontTag(null,2) + "<B><A HREF=\""
|
||||||
|
+ rdat.getEncodedServletPath(href) + "\">" + StringUtil.encodeHTML(conf.getName())
|
||||||
|
+ "</A></B> (" + StringUtil.encodeHTML(conf.getEnclosingSIG().getName()) + ")</FONT>\n");
|
||||||
|
if (conf.anyUnread())
|
||||||
|
out.write(" <IMG SRC=\"" + rdat.getFullImagePath("tag_new.gif")
|
||||||
|
+ "\" ALT=\"New!\" BORDER=0 WIDTH=40 HEIGHT=20>\n");
|
||||||
|
out.write("</TD>\n</TR>\n");
|
||||||
|
|
||||||
|
} // end while
|
||||||
|
|
||||||
|
out.write("</TABLE>\n");
|
||||||
|
|
||||||
|
} // end if
|
||||||
|
else
|
||||||
|
out.write(rdat.getStdFontTag(null,2) + "<EM>You have no conferences in your hotlist.</EM></FONT>\n");
|
||||||
|
|
||||||
// write the link at the end
|
// write the link at the end
|
||||||
out.write("<P>" + rdat.getStdFontTag(null,1) + "<B>[ <A HREF=\"" + rdat.getEncodedServletPath("TODO")
|
out.write("<P>" + rdat.getStdFontTag(null,1) + "<B>[ <A HREF=\"" + rdat.getEncodedServletPath("TODO")
|
||||||
|
|
|
@ -154,7 +154,7 @@ public class TopicListing implements JSPRender
|
||||||
|
|
||||||
public boolean canAddToHotlist()
|
public boolean canAddToHotlist()
|
||||||
{
|
{
|
||||||
return false; // TODO: fix this
|
return conf.canAddToHotlist();
|
||||||
|
|
||||||
} // end canAddToHotlist
|
} // end canAddToHotlist
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,13 @@
|
||||||
SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>" ALT="Read New" WIDTH=80 HEIGHT=24
|
SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>" ALT="Read New" WIDTH=80 HEIGHT=24
|
||||||
BORDER=0></A>
|
BORDER=0></A>
|
||||||
<% } // end if %>
|
<% } // end if %>
|
||||||
<A HREF="<%= "confops?" + data.getLocator() + "&cmd=Q" %>"><IMG
|
<A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=Q") %>"><IMG
|
||||||
SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>" ALT="Manage" WIDTH=80 HEIGHT=24
|
SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>" ALT="Manage" WIDTH=80 HEIGHT=24
|
||||||
BORDER=0></A>
|
BORDER=0></A>
|
||||||
<% if (data.canAddToHotlist()) { %>
|
<% if (data.canAddToHotlist()) { %>
|
||||||
<A HREF="TODO"><IMG SRC="<%= rdat.getFullImagePath("bn_add_to_hotlist.gif") %>"
|
<A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=H") %>"><IMG
|
||||||
ALT="Add to HotList" WIDTH=80 HEIGHT=24 BORDER=0></A>
|
SRC="<%= rdat.getFullImagePath("bn_add_to_hotlist.gif") %>" ALT="Add to HotList" WIDTH=80
|
||||||
|
HEIGHT=24 BORDER=0></A>
|
||||||
<% } // end if %>
|
<% } // end if %>
|
||||||
</DIV>
|
</DIV>
|
||||||
<% if (data.anyTopics()) { %>
|
<% if (data.anyTopics()) { %>
|
||||||
|
|
BIN
web/images/tag_new.gif
Normal file
BIN
web/images/tag_new.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 335 B |
Loading…
Reference in New Issue
Block a user