diff --git a/TODO b/TODO index 131437a..6ba46b5 100644 --- a/TODO +++ b/TODO @@ -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 diff --git a/setup/database.sql b/setup/database.sql index 4750e40..dec6198 100644 --- a/setup/database.sql +++ b/setup/database.sql @@ -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.) diff --git a/src/com/silverwrist/venice/core/impl/ReadOnlyVector.java b/src/com/silverwrist/util/collections/ReadOnlyVector.java similarity index 91% rename from src/com/silverwrist/venice/core/impl/ReadOnlyVector.java rename to src/com/silverwrist/util/collections/ReadOnlyVector.java index a43efa4..07022c1 100644 --- a/src/com/silverwrist/venice/core/impl/ReadOnlyVector.java +++ b/src/com/silverwrist/util/collections/ReadOnlyVector.java @@ -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 , * 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 - diff --git a/src/com/silverwrist/util/rcache/ReferenceCache.java b/src/com/silverwrist/util/rcache/ReferenceCache.java new file mode 100644 index 0000000..ebc12cc --- /dev/null +++ b/src/com/silverwrist/util/rcache/ReferenceCache.java @@ -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 . + * + * 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 , + * 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; i0) + { // 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. + * + * 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 , + * 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 diff --git a/src/com/silverwrist/venice/core/impl/ReferencedData.java b/src/com/silverwrist/util/rcache/ReferencedData.java similarity index 87% rename from src/com/silverwrist/venice/core/impl/ReferencedData.java rename to src/com/silverwrist/util/rcache/ReferencedData.java index 8f021c3..c59a3b7 100644 --- a/src/com/silverwrist/venice/core/impl/ReferencedData.java +++ b/src/com/silverwrist/util/rcache/ReferencedData.java @@ -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 , * 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 diff --git a/src/com/silverwrist/util/rcache/ReferencedDataBuilder.java b/src/com/silverwrist/util/rcache/ReferencedDataBuilder.java new file mode 100644 index 0000000..821db2f --- /dev/null +++ b/src/com/silverwrist/util/rcache/ReferencedDataBuilder.java @@ -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 . + * + * 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 , + * 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 diff --git a/src/com/silverwrist/util/rcache/ReferencedDataBuilderException.java b/src/com/silverwrist/util/rcache/ReferencedDataBuilderException.java new file mode 100644 index 0000000..36a978e --- /dev/null +++ b/src/com/silverwrist/util/rcache/ReferencedDataBuilderException.java @@ -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 . + * + * 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 , + * 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 diff --git a/src/com/silverwrist/venice/core/impl/BackgroundSIGPurge.java b/src/com/silverwrist/venice/core/impl/BackgroundSIGPurge.java index 43df8a4..d5c57c1 100644 --- a/src/com/silverwrist/venice/core/impl/BackgroundSIGPurge.java +++ b/src/com/silverwrist/venice/core/impl/BackgroundSIGPurge.java @@ -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, * 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 diff --git a/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java b/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java index ab3f488..102af25 100644 --- a/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java @@ -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 *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java b/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java index dcff4ed..5e13555 100644 --- a/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java @@ -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; diff --git a/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java b/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java index 302800d..8547321 100644 --- a/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java @@ -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; diff --git a/src/com/silverwrist/venice/core/impl/UserBackend.java b/src/com/silverwrist/venice/core/impl/UserBackend.java index c41b836..78a4eb8 100644 --- a/src/com/silverwrist/venice/core/impl/UserBackend.java +++ b/src/com/silverwrist/venice/core/impl/UserBackend.java @@ -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 diff --git a/src/com/silverwrist/venice/core/impl/UserContextImpl.java b/src/com/silverwrist/venice/core/impl/UserContextImpl.java index 365e0b6..de536b2 100644 --- a/src/com/silverwrist/venice/core/impl/UserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/UserContextImpl.java @@ -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,10 +871,10 @@ 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 int othe two hide flags. + // Convert the "hide mode" value into the two hide flags. boolean hide_dir = (hide_mode!=SIGContext.HIDE_NONE); boolean hide_search = (hide_mode==SIGContext.HIDE_BOTH); @@ -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 *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/UserProfileImpl.java b/src/com/silverwrist/venice/core/impl/UserProfileImpl.java index 4339ab0..2309043 100644 --- a/src/com/silverwrist/venice/core/impl/UserProfileImpl.java +++ b/src/com/silverwrist/venice/core/impl/UserProfileImpl.java @@ -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; diff --git a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java index e2ae127..ff4d6ab 100644 --- a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java +++ b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java @@ -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 - else - { // this is an extra reference to the SIGDataObject - sd.rd_addRef(); - if (logger.isDebugEnabled()) - logger.debug("...using cached object"); + } // 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 + 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 - else - { // this is an extra reference to the ConferenceDataObject - cd.rd_addRef(); - if (logger.isDebugEnabled()) - logger.debug("...using cached object"); + } // 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 + 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 diff --git a/src/com/silverwrist/venice/security/AuditRecord.java b/src/com/silverwrist/venice/security/AuditRecord.java index 47f59b7..a724caa 100644 --- a/src/com/silverwrist/venice/security/AuditRecord.java +++ b/src/com/silverwrist/venice/security/AuditRecord.java @@ -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 *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/security/Capability.java b/src/com/silverwrist/venice/security/Capability.java index c3c0405..b94a19c 100644 --- a/src/com/silverwrist/venice/security/Capability.java +++ b/src/com/silverwrist/venice/security/Capability.java @@ -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<% } %> <% if (data.displayWelcome()) { %> <% rdat.writeContentHeader(out,rdat.getStockMessage("welcome-top"),null); %> - <%= rdat.getStdFontTag(null,1) %><%= rdat.getStockMessage(out,"welcome"); %>

+ <%= rdat.getStdFontTag(null,1) %><%= rdat.getStockMessage("welcome") %>

<% } // end if %> <% rdat.writeContentHeader(out,rdat.getStockMessage("currents-top"),null); %> <% int ntp = data.getNumTopPosts(); %>