broke out the object cache functionality; generalized ReadOnlyVector;

finally implemented background sweeps of unreferenced cache objects;
anonymous user, when viewing profiles, now sees them as if all "privacy"
flags were switched on
This commit is contained in:
Eric J. Bowersox 2001-03-26 06:11:11 +00:00
parent 15a7fa56d2
commit 7e72407b84
29 changed files with 601 additions and 233 deletions

7
TODO
View File

@ -2,20 +2,13 @@ Lots!
- Unimplemented functions on the SIG Administration page:
Set SIG Features (sigadmin, command=F)
View Audit Records (needs to be added)
- Unimplemented functions in the system admin menu:
Set Global Parameters
View/Edit Banned Users
User Account Management
View Audit Records (needs to be added)
(More stuff needs to be added, I'm just not sure what.)
- Should we provide the sysadmin the ability to disable SIG creation for
non-admin users? Maybe there needs to be a "global" set of levels that
aren't hardcoded. Where do they get stored? The database? (Maybe the
nice shiny new "globals" table?)
- Unimplemented functions on the Top page:
Customize Sideboxes

View File

@ -40,7 +40,8 @@ CREATE TABLE globals (
max_sig_mbr_page INT NOT NULL,
max_conf_mbr_page INT NOT NULL,
fp_posts INT NOT NULL,
num_audit_page INT NOT NULL
num_audit_page INT NOT NULL,
sig_create_lvl INT NOT NULL
);
# The audit records table. Most "major" events add a record to this table.
@ -1325,8 +1326,8 @@ INSERT INTO refsigftr (ftr_code, is_default, is_locked, is_hidden, require_read,
# Initialize the system globals table.
INSERT INTO globals (posts_per_page, old_posts_at_top, max_search_page, max_sig_mbr_page, max_conf_mbr_page,
fp_posts, num_audit_page)
VALUES (20, 2, 20, 50, 50, 10, 100);
fp_posts, num_audit_page, sig_create_lvl)
VALUES (20, 2, 20, 50, 50, 10, 100, 1000);
# Add the 'Anonymous Honyak' user to the users table.
# (Do 'SELECT * FROM users WHERE is_anon = 1' to retrieve the AC user details.)

View File

@ -7,7 +7,7 @@
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Community System.
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
@ -15,11 +15,11 @@
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
package com.silverwrist.util.collections;
import java.util.*;
class ReadOnlyVector extends AbstractList
public class ReadOnlyVector extends AbstractList
{
/*--------------------------------------------------------------------------------
* Attributes
@ -33,7 +33,7 @@ class ReadOnlyVector extends AbstractList
*--------------------------------------------------------------------------------
*/
ReadOnlyVector(Vector vec)
public ReadOnlyVector(Vector vec)
{
my_vec = vec;
my_vec.trimToSize();
@ -70,4 +70,3 @@ class ReadOnlyVector extends AbstractList
} // end size
} // end class ReadOnlyVector

View File

@ -0,0 +1,162 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.util.rcache;
import java.util.*;
import com.silverwrist.util.collections.*;
public class ReferenceCache
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private HashMap the_data;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public ReferenceCache()
{
the_data = new HashMap();
} // end constructor
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public synchronized ReferencedData get(Object key)
{
ReferencedData rc = (ReferencedData)(the_data.get(key));
if (rc!=null)
rc.rd_addRef();
return rc;
} // end get
public synchronized ReferencedData getOrCreate(Object key, ReferencedDataBuilder builder)
throws ReferencedDataBuilderException
{
ReferencedData rc = (ReferencedData)(the_data.get(key));
if (rc==null)
{ // use the builder to build one
rc = builder.build(key);
if (rc!=null)
the_data.put(key,rc);
} // end if
else // just add a reference
rc.rd_addRef();
return rc;
} // end getOrCreate
public void register(ReferencedData data)
{
Object key = data.rd_getKey();
synchronized (this)
{ // see if it's in the cache, if not, add it
if (the_data.get(key)!=null)
throw new ReferenceCacheException("object already in cache",key);
// dump it in the object cache
the_data.put(key,data);
} // end synchronized block
} // end register
public synchronized void detach(Object key)
{
the_data.remove(key);
} // end detach
public void sweep()
{
int count = 0;
synchronized (this)
{ // bail out early if possible
if (the_data.size()==0)
return;
// provide a storage bin for all keys we decide to 86
Object keyzap[] = new Object[the_data.size()];
Iterator it = the_data.values().iterator();
while (it.hasNext())
{ // check each value we contain in turn
ReferencedData rd = (ReferencedData)(it.next());
if (rd.rd_unreferenced())
keyzap[count++] = rd.rd_getKey();
} // end while
for (int i=0; i<count; i++)
the_data.remove(keyzap[i]);
} // end synchronized block
} // end sweep
public List sweepReturn()
{
Vector rc = new Vector();
int count = 0;
synchronized (this)
{ // bail out early if possible
if (the_data.size()>0)
{ // provide a storage bin for all keys we decide to 86
Object keyzap[] = new Object[the_data.size()];
Iterator it = the_data.values().iterator();
while (it.hasNext())
{ // check each value we contain in turn
ReferencedData rd = (ReferencedData)(it.next());
if (rd.rd_unreferenced())
keyzap[count++] = rd.rd_getKey();
else
{ // add another reference and tack it onto the list
rd.rd_addRef();
rc.add(rd);
} // end else
} // end while
for (int i=0; i<count; i++)
the_data.remove(keyzap[i]);
} // end if
} // end synchronized block
return new ReadOnlyVector(rc);
} // end sweepReturn
} // end ReferenceCache

View File

@ -0,0 +1,52 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.util.rcache;
public class ReferenceCacheException extends RuntimeException
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private Object keyval;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public ReferenceCacheException(String msg, Object keyval)
{
super("[keyval " + keyval.toString() + "]: " + msg);
this.keyval = keyval;
} // end constructor
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public Object getKeyVal()
{
return keyval;
} // end getKeyVal
} // end class ReferenceCacheException

View File

@ -7,7 +7,7 @@
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Community System.
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
@ -15,7 +15,7 @@
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
package com.silverwrist.util.rcache;
public interface ReferencedData
{
@ -25,4 +25,6 @@ public interface ReferencedData
public abstract boolean rd_unreferenced();
public abstract Object rd_getKey();
} // end interface ReferencedData

View File

@ -0,0 +1,24 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.util.rcache;
public interface ReferencedDataBuilder
{
public abstract ReferencedData build(Object key) throws ReferencedDataBuilderException;
} // end interface ReferencedDataBuilder

View File

@ -0,0 +1,52 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.util.rcache;
public class ReferencedDataBuilderException extends Exception
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private Exception target;
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
public ReferencedDataBuilderException(Exception target)
{
super("Error building new object: " + target.getMessage());
this.target = target;
} // end constructor
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public Exception getTarget()
{
return target;
} // end getTarget
} // end class ReferencedDataBuilderException

View File

@ -21,6 +21,7 @@ import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.ParallelRunQueue;
import com.silverwrist.util.rcache.ReferenceCache;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.core.DataException;
import com.silverwrist.venice.core.InternalStateError;
@ -45,7 +46,7 @@ class BackgroundSIGPurge implements Runnable
private int sigid;
private int num_confs;
private int max_confid;
private Hashtable conf_objects;
private ReferenceCache conf_refcache;
/*--------------------------------------------------------------------------------
* Constructor
@ -53,7 +54,7 @@ class BackgroundSIGPurge implements Runnable
*/
BackgroundSIGPurge(EngineBackend engine, DataPool datapool, UserBackend user, int sigid, int num_confs,
int max_confid, Hashtable conf_objects)
int max_confid, ReferenceCache conf_refcache)
{
this.engine = engine;
this.datapool = datapool;
@ -61,7 +62,7 @@ class BackgroundSIGPurge implements Runnable
this.sigid = sigid;
this.num_confs = num_confs;
this.max_confid = max_confid;
this.conf_objects = conf_objects;
this.conf_refcache = conf_refcache;
} // end constructor
@ -100,10 +101,10 @@ class BackgroundSIGPurge implements Runnable
for (int i=0; i<conferences; i++)
{ // look to see if there's a conference SIG object first
Integer key = new Integer(conf_ids[i]);
ConferenceSIGContext confobj = (ConferenceSIGContext)(conf_objects.get(key));
ConferenceSIGContext confobj = (ConferenceSIGContext)(conf_refcache.get(key));
if (confobj!=null)
{ // OK, there's an object - do the delete internally and release the object
conf_objects.remove(key);
conf_refcache.detach(key);
confobj.delete(user);
confobj.rd_release();

View File

@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.collections.*;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.core.*;

View File

@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.collections.*;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.security.AuditRecord;
import com.silverwrist.venice.security.DefaultLevels;
@ -185,6 +186,12 @@ class ConferenceCoreData implements ConferenceData
} // end rd_unreferenced
public Object rd_getKey()
{
return new Integer(confid);
} // end rd_getKey
/*--------------------------------------------------------------------------------
* Implementations from interface ConferenceData
*--------------------------------------------------------------------------------

View File

@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.sql.Connection;
import java.util.Date;
import java.util.List;
import com.silverwrist.util.rcache.ReferencedData;
import com.silverwrist.venice.core.DataException;
public interface ConferenceData extends ReferencedData

View File

@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.sql.Connection;
import java.util.Date;
import java.util.List;
import com.silverwrist.util.rcache.ReferencedData;
import com.silverwrist.venice.core.DataException;
public interface ConferenceSIGContext extends ReferencedData

View File

@ -261,6 +261,12 @@ class ConferenceSIGContextImpl implements ConferenceSIGContext
} // end rd_unreferences
public Object rd_getKey()
{
return new Integer(confid);
} // end rd_getKey
/*--------------------------------------------------------------------------------
* Implementations from interface ConferenceSIGContext
*--------------------------------------------------------------------------------

View File

@ -20,6 +20,8 @@ package com.silverwrist.venice.core.impl;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.collections.*;
import com.silverwrist.util.rcache.ReferencedData;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.htmlcheck.*;
import com.silverwrist.venice.security.DefaultLevels;
@ -237,6 +239,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (deleted)
throw new DataException("This conference has been deleted.");
confdata = sig.getConferenceDataObject(confid);
if (confdata!=null)
sig.saveMRU("conf",confdata);
// clear cache when we get the real confdata
cache = null;
@ -257,6 +261,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
try
{ // attempt to load the ConferenceSIGContext
confdata = sig.getConferenceDataObject(confid);
if (confdata!=null)
sig.saveMRU("conf",confdata);
} // end try
catch (DataException e)
@ -1476,6 +1482,12 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end realFullName
public void saveMRU(String tag, ReferencedData data)
{
sig.saveMRU(tag,data);
} // end saveMRU
/*--------------------------------------------------------------------------------
* Implementations from interface SIGBackend
*--------------------------------------------------------------------------------

View File

@ -38,6 +38,8 @@ public interface EngineBackend
public static final int IP_MAXCONFMEMBERDISPLAY = 4;
public static final int IP_NUMFRONTPAGEPOSTS = 5;
public static final int IP_NUMAUDITRECSPERPAGE = 6;
public static final int IP_CREATESIGLVL = 7;
public static final int IPC_NUM_PARAMS = 8;
public abstract SimpleEmailer createEmailer();

View File

@ -21,6 +21,8 @@ import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.collections.*;
import com.silverwrist.util.rcache.*;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.security.AuditRecord;
@ -29,6 +31,35 @@ import com.silverwrist.venice.security.DefaultLevels;
class SIGCoreData implements SIGData, SIGDataBackend
{
/*--------------------------------------------------------------------------------
* Internal class that creates new ConferenceSIGContextImpl objects
*--------------------------------------------------------------------------------
*/
protected class ConferenceSIGContextImplCreator implements ReferencedDataBuilder
{
protected ConferenceSIGContextImplCreator()
{ // do nothing
} // end constructor
public ReferencedData build(Object key) throws ReferencedDataBuilderException
{
Integer xconf = (Integer)key;
try
{ // create the desired object
return new ConferenceSIGContextImpl(engine,SIGCoreData.this,datapool,xconf.intValue());
} // end try
catch (DataException e)
{ // rethrow as a "wrapped" exception
throw new ReferencedDataBuilderException(e);
} // end catch
} // end build
} // end class ConferenceCoreDataCreator
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
@ -68,7 +99,8 @@ class SIGCoreData implements SIGData, SIGDataBackend
private String alias; // the community alias value
private boolean public_sig; // is this a public SIG?
private BitSet features; // set of available features
private Hashtable conf_objects = new Hashtable(); // holder for ConferenceSIGContextImpl objects
private ReferenceCache conf_refcache = new ReferenceCache();
private ConferenceSIGContextImplCreator conf_creator = new ConferenceSIGContextImplCreator();
private boolean deleted = false; // has this SIG been deleted?
/*--------------------------------------------------------------------------------
@ -258,6 +290,12 @@ class SIGCoreData implements SIGData, SIGDataBackend
} // end rd_unreferenced
public Object rd_getKey()
{
return new Integer(sigid);
} // end rd_getKey
/*--------------------------------------------------------------------------------
* Implementations from interface SIGData
*--------------------------------------------------------------------------------
@ -1393,25 +1431,21 @@ class SIGCoreData implements SIGData, SIGDataBackend
if (logger.isDebugEnabled())
logger.debug("getConferenceDataObject(" + confid + ")...");
Integer the_confid = new Integer(confid);
ConferenceSIGContext csc = (ConferenceSIGContext)(conf_objects.get(the_confid));
if (csc==null)
{ // create a new ConferenceSIGContextImpl object and save it off
csc = new ConferenceSIGContextImpl(engine,this,datapool,confid);
conf_objects.put(the_confid,csc);
if (logger.isDebugEnabled())
logger.debug("...created new object");
try
{ // delegate to the conf_refcache and conf_creator objects
return (ConferenceSIGContext)(conf_refcache.getOrCreate(new Integer(confid),conf_creator));
} // end if
} // end try
catch (ReferencedDataBuilderException e)
{ // this may be a DataException, or it may not
Exception e2 = e.getTarget();
if (e2 instanceof DataException)
throw (DataException)e2;
else
{ // this is an extra reference to the ConferenceSIGContext
csc.rd_addRef();
if (logger.isDebugEnabled())
logger.debug("...using cached object");
throw new InternalStateError("unknown creation exception thrown in getConferenceDataObject: "
+ e2.getClass().getName(),e2);
} // end else
return csc;
} // end catch
} // end getConferenceDataObject
@ -1420,16 +1454,7 @@ class SIGCoreData implements SIGData, SIGDataBackend
if (logger.isDebugEnabled())
logger.debug("detachConferenceDataObject(" + confid + ")...");
Integer the_confid = new Integer(confid);
ConferenceSIGContext csc = (ConferenceSIGContext)(conf_objects.get(the_confid));
if (csc!=null)
{ // remove from the hashtable
conf_objects.remove(the_confid);
csc.rd_release();
if (logger.isDebugEnabled())
logger.debug("...reference released");
} // end if
conf_refcache.detach(new Integer(confid));
} // end detachConferenceDataObject
@ -1452,17 +1477,7 @@ class SIGCoreData implements SIGData, SIGDataBackend
cdata.rd_release();
rcs = null;
synchronized (this)
{ // Register this object with our local cache of ConferenceSIGData objects.
Integer the_confid = new Integer(conf.getConfID());
if (conf_objects.get(the_confid)!=null)
throw new InternalStateError("ConfID " + the_confid + " already exists...but it CAN'T HAVE!");
// throw an extra reference on it and dump it in the object cache
conf.rd_addRef();
conf_objects.put(the_confid,conf);
} // end synchronized block
conf_refcache.register(conf); // register this object with our local cache
return conf; // pass it up to the next level
@ -1853,13 +1868,19 @@ class SIGCoreData implements SIGData, SIGDataBackend
// Delete the rest of the gunk in the background; use another thread to do it.
BackgroundSIGPurge purger = new BackgroundSIGPurge(engine,datapool,user,sigid,conf_count,conf_max,
conf_objects);
conf_refcache);
Thread thrd = new Thread(purger);
thrd.setPriority(Thread.NORM_PRIORITY-1);
thrd.start();
} // end delete
public void sweepCache()
{
conf_refcache.sweep();
} // end sweepCache
/*--------------------------------------------------------------------------------
* Implementations from interface SIGDataBackend
*--------------------------------------------------------------------------------

View File

@ -7,7 +7,7 @@
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Community System.
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.util.BitSet;
import java.util.Date;
import java.util.List;
import com.silverwrist.util.rcache.ReferencedData;
import com.silverwrist.venice.core.AccessError;
import com.silverwrist.venice.core.ContactInfo;
import com.silverwrist.venice.core.DataException;
@ -150,4 +151,6 @@ public interface SIGData extends ReferencedData
public abstract void delete(UserBackend user) throws DataException;
public abstract void sweepCache();
} // end interface SIGData

View File

@ -21,6 +21,8 @@ import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.collections.*;
import com.silverwrist.util.rcache.ReferencedData;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.security.AuditRecord;
import com.silverwrist.venice.security.Capability;
@ -180,6 +182,8 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
if (deleted)
throw new DataException("This SIG has been deleted.");
sigdata = engine.getSIGDataObject(sigid);
if (sigdata!=null)
user.saveMRU("sig",sigdata);
// clear cache when we get the real sigdata
cache = null;
@ -199,6 +203,8 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
try
{ // attempt to load the SIGDataObject
sigdata = engine.getSIGDataObject(sigid);
if (sigdata!=null)
user.saveMRU("sig",sigdata);
} // end try
catch (DataException e)
@ -1397,6 +1403,12 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
} // end realFullName
public void saveMRU(String tag, ReferencedData data)
{
user.saveMRU(tag,data);
} // end saveMRU
/*--------------------------------------------------------------------------------
* Implementations from interface SIGBackend
*--------------------------------------------------------------------------------

View File

@ -22,6 +22,7 @@ import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.collections.*;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.security.AuditRecord;
import com.silverwrist.venice.security.Capability;

View File

@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.collections.*;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.htmlcheck.*;
import com.silverwrist.venice.security.AuditRecord;

View File

@ -17,6 +17,7 @@
*/
package com.silverwrist.venice.core.impl;
import com.silverwrist.util.rcache.ReferencedData;
import com.silverwrist.venice.core.DataException;
public interface UserBackend
@ -37,4 +38,6 @@ public interface UserBackend
public abstract String realFullName() throws DataException;
public abstract void saveMRU(String tag, ReferencedData data);
} // end interface UserBackend

View File

@ -22,6 +22,8 @@ import java.sql.*;
import org.apache.log4j.*;
import com.silverwrist.util.LocaleFactory;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.collections.*;
import com.silverwrist.util.rcache.ReferencedData;
import com.silverwrist.venice.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.db.*;
@ -62,6 +64,7 @@ class UserContextImpl implements UserContext, UserBackend
private String full_name = null; // my full name (cached)
private Locale my_locale = null; // my default locale (cached)
private TimeZone my_tz = null; // my default timezone (cached)
private Hashtable mru_cache = new Hashtable(); // MRU cache for ReferencedData objects
/*--------------------------------------------------------------------------------
* Constructor
@ -82,6 +85,14 @@ class UserContextImpl implements UserContext, UserBackend
protected void finalize()
{
Iterator it = mru_cache.values().iterator();
while (it.hasNext())
{ // release all our ReferencedData objects
ReferencedData rd = (ReferencedData)(it.next());
rd.rd_release();
} // end while
engine = null;
datapool = null;
username = null;
@ -860,7 +871,7 @@ class UserContextImpl implements UserContext, UserBackend
public SIGContext createSIG(String name, String alias, String language, String synopsis, String rules,
String joinkey, int hide_mode) throws DataException, AccessError
{
if (!(Capability.canCreateSIG(level)))
if (!canCreateSIG())
throw new AccessError("You are not authorized to create new SIGs.");
// Convert the "hide mode" value into the two hide flags.
@ -884,7 +895,7 @@ class UserContextImpl implements UserContext, UserBackend
public boolean canCreateSIG()
{
return Capability.canCreateSIG(level);
return (level>=engine.getParamInt(EngineBackend.IP_CREATESIGLVL));
} // end canCreateSIG
@ -1102,6 +1113,16 @@ class UserContextImpl implements UserContext, UserBackend
} // end realFullName
public void saveMRU(String tag, ReferencedData data)
{
ReferencedData old = (ReferencedData)(mru_cache.get(tag));
data.rd_addRef();
mru_cache.put(tag,data);
if (old!=null)
old.rd_release();
} // end saveMRU
/*--------------------------------------------------------------------------------
* Operations private to implementation package
*--------------------------------------------------------------------------------

View File

@ -156,6 +156,7 @@ class UserProfileImpl implements UserProfile
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next())
{ // load all the record data
boolean me_anon = user.userIsAnonymous();
given_name = rs.getString("given_name");
family_name = rs.getString("family_name");
String blort = rs.getString("middle_init");
@ -166,7 +167,7 @@ class UserProfileImpl implements UserProfile
prefix = rs.getString("prefix");
suffix = rs.getString("suffix");
company = rs.getString("company");
if (!override && rs.getBoolean("pvt_addr"))
if (!override && (me_anon || rs.getBoolean("pvt_addr")))
{ // enforce address privacy
addr1 = null;
addr2 = null;
@ -183,7 +184,7 @@ class UserProfileImpl implements UserProfile
region = rs.getString("region");
postal_code = rs.getString("pcode");
country = rs.getString("country");
if (!override && rs.getBoolean("pvt_phone"))
if (!override && (me_anon || rs.getBoolean("pvt_phone")))
{ // enforce phone privacy
phone = null;
mobile = null;
@ -196,13 +197,13 @@ class UserProfileImpl implements UserProfile
} // end else
if (!override && rs.getBoolean("pvt_fax"))
if (!override && (me_anon || rs.getBoolean("pvt_fax")))
fax = null;
else
fax = rs.getString("fax");
real_email = rs.getString("email");
if (!override && rs.getBoolean("pvt_email"))
if (!override && (me_anon || rs.getBoolean("pvt_email")))
email = null;
else
email = real_email;

View File

@ -23,6 +23,8 @@ import org.apache.log4j.*;
import org.w3c.dom.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.DOMElementHelper;
import com.silverwrist.util.collections.*;
import com.silverwrist.util.rcache.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.htmlcheck.*;
@ -278,6 +280,104 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end class MasterSideBoxList
/*--------------------------------------------------------------------------------
* Internal cache sweeper class information.
*--------------------------------------------------------------------------------
*/
protected class CacheSweeper implements Runnable
{
public void run()
{
for (;;)
{ // this is a background thread that runs always
try
{ // wait for a little while
Thread.sleep(10000);
} // end try
catch (InterruptedException e)
{ // if we're interrupted, just schedule the next run a little early
} // end catch
// sweep the SIG cache first
List sigs = sig_refcache.sweepReturn();
Iterator it = sigs.iterator();
while (it.hasNext())
{ // perform subsweeps on the SIG data
SIGData sig = (SIGData)(it.next());
sig.sweepCache();
sig.rd_release();
} // end while
// now sweep other caches
conf_refcache.sweep();
} // end for (ever)
} // end run
} // end class CacheSweeper
/*--------------------------------------------------------------------------------
* Internal class for creating new SIGCoreData objects.
*--------------------------------------------------------------------------------
*/
protected class SIGCoreDataCreator implements ReferencedDataBuilder
{
protected SIGCoreDataCreator()
{ // do nothing
} // end constructor
public ReferencedData build(Object key) throws ReferencedDataBuilderException
{
Integer xsigid = (Integer)key;
try
{ // create the desired object
return new SIGCoreData(VeniceEngineImpl.this,datapool,xsigid.intValue());
} // end try
catch (DataException e)
{ // rethrow as a "wrapped" exception
throw new ReferencedDataBuilderException(e);
} // end catch
} // end build
} // end class SIGCoreDataCreator
/*--------------------------------------------------------------------------------
* Internal class for creating new ConferenceCoreData objects.
*--------------------------------------------------------------------------------
*/
protected class ConferenceCoreDataCreator implements ReferencedDataBuilder
{
protected ConferenceCoreDataCreator()
{ // do nothing
} // end constructor
public ReferencedData build(Object key) throws ReferencedDataBuilderException
{
Integer xconf = (Integer)key;
try
{ // create the desired object
return new ConferenceCoreData(VeniceEngineImpl.this,datapool,xconf.intValue());
} // end try
catch (DataException e)
{ // rethrow as a "wrapped" exception
throw new ReferencedDataBuilderException(e);
} // end catch
} // end build
} // end class ConferenceCoreDataCreator
/*--------------------------------------------------------------------------------
* Static data values
*--------------------------------------------------------------------------------
@ -296,10 +396,12 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
private Properties email_props = null; // email properties
private javax.mail.Session mailsession = null; // email session object
private Hashtable stock_messages = null; // stock messages holder
private Hashtable sig_objects = new Hashtable(); // holder for SIGCoreData objects
private ReferenceCache sig_refcache = new ReferenceCache();
private SIGCoreDataCreator sig_creator = new SIGCoreDataCreator();
private VeniceFeatureDef[] features; // master feature table
private Hashtable feature_syms = new Hashtable(); // hashtable mapping symbols to features
private Hashtable conf_objects = new Hashtable(); // holder for ConferenceCoreData objects
private ReferenceCache conf_refcache = new ReferenceCache();
private ConferenceCoreDataCreator conf_creator = new ConferenceCoreDataCreator();
private HTMLCheckerConfig[] html_configs; // holder for HTML checker configurations
private int[] gp_ints; // global integer parameters
private MasterSideBox[] sideboxes; // master sidebox table
@ -336,7 +438,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
{
final String query =
"SELECT posts_per_page, old_posts_at_top, max_search_page, max_sig_mbr_page, max_conf_mbr_page, "
+ "fp_posts, num_audit_page FROM globals;";
+ "fp_posts, num_audit_page, sig_create_lvl FROM globals;";
ResultSet rs = stmt.executeQuery(query);
if (!(rs.next()))
throw new DataException("Globals table does not appear to be loaded!");
@ -349,6 +451,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
gp_ints[IP_MAXCONFMEMBERDISPLAY] = rs.getInt(5);
gp_ints[IP_NUMFRONTPAGEPOSTS] = rs.getInt(6);
gp_ints[IP_NUMAUDITRECSPERPAGE] = rs.getInt(7);
gp_ints[IP_CREATESIGLVL] = rs.getInt(8);
} // end loadDefaults
@ -493,7 +596,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end catch
// Allocate the global parameter arrays.
gp_ints = new int[7];
gp_ints = new int[IPC_NUM_PARAMS];
// initialize anything that requires us to pull from the database
Connection conn = null;
@ -634,6 +737,12 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
cfg.addOutputFilter(html_filter);
html_configs[HTMLC_ESCAPE_BODY_PSEUD] = cfg;
// Start the cache sweeper.
Thread thrd = new Thread(new CacheSweeper());
thrd.setPriority(Thread.currentThread().getPriority()-2);
thrd.setDaemon(true);
thrd.start();
if (logger.isDebugEnabled())
logger.debug("initialize() complete :-)");
@ -1555,50 +1664,37 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end getLanguageNameForCode
public synchronized SIGData getSIGDataObject(int sigid) throws DataException
public SIGData getSIGDataObject(int sigid) throws DataException
{
checkInitialized();
if (logger.isDebugEnabled())
logger.debug("getSIGDataObject(" + sigid + ")...");
Integer the_sigid = new Integer(sigid);
SIGData sd = (SIGData)(sig_objects.get(the_sigid));
if (sd==null)
{ // create a new SIGCoreData object and save it off
sd = new SIGCoreData(this,datapool,sigid);
sig_objects.put(the_sigid,sd);
if (logger.isDebugEnabled())
logger.debug("...created new object");
try
{ // delegate to the sig_refcache and sig_creator objects
return (SIGData)(sig_refcache.getOrCreate(new Integer(sigid),sig_creator));
} // end if
} // end try
catch (ReferencedDataBuilderException e)
{ // this may be a DataException, or it may not
Exception e2 = e.getTarget();
if (e2 instanceof DataException)
throw (DataException)e2;
else
{ // this is an extra reference to the SIGDataObject
sd.rd_addRef();
if (logger.isDebugEnabled())
logger.debug("...using cached object");
throw new InternalStateError("unknown creation exception thrown in getSIGDataObject: "
+ e2.getClass().getName(),e2);
} // end else
return sd;
} // end catch
} // end getSIGDataObject
public synchronized void detachSIGDataObject(int sigid)
public void detachSIGDataObject(int sigid)
{
checkInitialized();
if (logger.isDebugEnabled())
logger.debug("detachSIGDataObject(" + sigid + ")...");
Integer the_sigid = new Integer(sigid);
SIGData sd = (SIGData)(sig_objects.get(the_sigid));
if (sd!=null)
{ // pull the reference out of our hashtable
sig_objects.remove(the_sigid);
sd.rd_release();
if (logger.isDebugEnabled())
logger.debug("...reference detached");
} // end if
sig_refcache.detach(new Integer(sigid));
} // end detachSIGDataObject
@ -1680,21 +1776,13 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end getDefaultFeaturesMask
public synchronized void registerNewSIG(SIGData sig)
public void registerNewSIG(SIGData sig)
{
checkInitialized();
if (logger.isDebugEnabled())
logger.debug("registerNewSIG(" + sig.getID() + ")...");
Integer the_sigid = new Integer(sig.getID());
if (sig_objects.get(the_sigid)!=null)
throw new InternalStateError("SIGID " + the_sigid + " already exists...but it CAN'T HAVE!");
// throw an extra reference on it and dump it in the object cache
sig.rd_addRef();
sig_objects.put(the_sigid,sig);
if (logger.isDebugEnabled())
logger.debug("...registered new object");
sig_refcache.register(sig);
} // end registerNewSIG
@ -1718,50 +1806,37 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end canAccessFeature
public synchronized ConferenceData getConferenceDataObject(int confid) throws DataException
public ConferenceData getConferenceDataObject(int confid) throws DataException
{
checkInitialized();
if (logger.isDebugEnabled())
logger.debug("getConferenceDataObject(" + confid + ")...");
Integer the_confid = new Integer(confid);
ConferenceData cd = (ConferenceData)(conf_objects.get(the_confid));
if (cd==null)
{ // create a new ConferenceCoreData object and save it off
cd = new ConferenceCoreData(this,datapool,confid);
conf_objects.put(the_confid,cd);
if (logger.isDebugEnabled())
logger.debug("...created new object");
try
{ // delegate to the conf_refcache and conf_creator objects
return (ConferenceData)(conf_refcache.getOrCreate(new Integer(confid),conf_creator));
} // end if
} // end try
catch (ReferencedDataBuilderException e)
{ // this may be a DataException, or it may not
Exception e2 = e.getTarget();
if (e2 instanceof DataException)
throw (DataException)e2;
else
{ // this is an extra reference to the ConferenceDataObject
cd.rd_addRef();
if (logger.isDebugEnabled())
logger.debug("...using cached object");
throw new InternalStateError("unknown creation exception thrown in getConferenceDataObject: "
+ e2.getClass().getName(),e2);
} // end else
return cd;
} // end catch
} // end getConferenceDataObject
public synchronized void detachConferenceDataObject(int confid)
public void detachConferenceDataObject(int confid)
{
checkInitialized();
if (logger.isDebugEnabled())
logger.debug("detachConferenceDataObject(" + confid + ")...");
Integer the_confid = new Integer(confid);
ConferenceData cd = (ConferenceData)(conf_objects.get(the_confid));
if (cd!=null)
{ // remove it from our hashtable
conf_objects.remove(the_confid);
cd.rd_release();
if (logger.isDebugEnabled())
logger.debug("...detached reference");
} // end if
conf_refcache.detach(new Integer(confid));
} // end detachConferenceDataObject
@ -1793,21 +1868,13 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end saveAuditRecord
public synchronized void registerNewConference(ConferenceData conf)
public void registerNewConference(ConferenceData conf)
{
checkInitialized();
if (logger.isDebugEnabled())
logger.debug("registerNewConference(" + conf.getID() + ")...");
Integer the_confid = new Integer(conf.getID());
if (conf_objects.get(the_confid)!=null)
throw new InternalStateError("ConfID " + the_confid + " already exists...but it CAN'T HAVE!");
// throw an extra reference on it and dump it in the object cache
conf.rd_addRef();
conf_objects.put(the_confid,conf);
if (logger.isDebugEnabled())
logger.debug("...registered new object");
conf_refcache.register(conf);
} // end registerNewConference

View File

@ -19,6 +19,7 @@ package com.silverwrist.venice.security;
import java.sql.*;
import java.util.*;
import com.silverwrist.util.collections.*;
import com.silverwrist.venice.db.SQLUtil;
import com.silverwrist.venice.core.AuditData;
import com.silverwrist.venice.core.DataException;
@ -26,43 +27,6 @@ import com.silverwrist.venice.core.InternalStateError;
public class AuditRecord implements AuditData
{
/*--------------------------------------------------------------------------------
* Private implementation of ReadOnlyVector
*--------------------------------------------------------------------------------
*/
static class ReadOnlyVector extends AbstractList
{
private Vector my_vec; // local vector
ReadOnlyVector(Vector vec)
{
my_vec = vec;
my_vec.trimToSize();
} // end constructor
protected void finalize() throws Throwable
{
my_vec = null;
super.finalize();
} // end finalize
public Object get(int index)
{
return my_vec.elementAt(index);
} // end get
public int size()
{
return my_vec.size();
} // end size
} // end class ReadOnlyVector
/*--------------------------------------------------------------------------------
* Internal class for caching description strings on load
*--------------------------------------------------------------------------------

View File

@ -85,12 +85,6 @@ public class Capability implements SecLevels
} // end showHiddenSIGMembers
public static boolean canCreateSIG(int level)
{
return (level>=GLOBAL_NORMAL);
} // end canCreateSIG
public static boolean hideHiddenConferences(int level)
{
return (level<SIG_ANYADMIN);

View File

@ -18,46 +18,10 @@
package com.silverwrist.venice.security;
import java.util.*;
import com.silverwrist.util.collections.*;
public class Role implements Comparable, SecLevels
{
/*--------------------------------------------------------------------------------
* Private implementation of ReadOnlyVector
*--------------------------------------------------------------------------------
*/
static class ReadOnlyVector extends AbstractList
{
private Vector my_vec; // local vector
ReadOnlyVector(Vector vec)
{
my_vec = vec;
my_vec.trimToSize();
} // end constructor
protected void finalize() throws Throwable
{
my_vec = null;
super.finalize();
} // end finalize
public Object get(int index)
{
return my_vec.elementAt(index);
} // end get
public int size()
{
return my_vec.size();
} // end size
} // end class ReadOnlyVector
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------

View File

@ -28,7 +28,7 @@
<% if (rdat.useHTMLComments()) { %><!-- Top content panel --><% } %>
<% if (data.displayWelcome()) { %>
<% rdat.writeContentHeader(out,rdat.getStockMessage("welcome-top"),null); %>
<%= rdat.getStdFontTag(null,1) %><%= rdat.getStockMessage(out,"welcome"); %></FONT><P>
<%= rdat.getStdFontTag(null,1) %><%= rdat.getStockMessage("welcome") %></FONT><P>
<% } // end if %>
<% rdat.writeContentHeader(out,rdat.getStockMessage("currents-top"),null); %>
<% int ntp = data.getNumTopPosts(); %>