some serious new feature implementation:

- cookie-based persistent logins
- expanded activity reporting
- "top" and "fixed" left menus are now dynamically generated from XML config,
  not hard coded
- error reporting enhanced and protection increased
- "About Venice" page first draft
- new means of "framing" static content within the Venice "frame"
- base page now includes the "footer" itself, "content" pages don't anymore
- general cleanup of some heavyweight old containers, replaced with faster
  Collections framework containers
- probably more, there's a LOT of stuff in here
This commit is contained in:
Eric J. Bowersox
2001-04-09 03:20:58 +00:00
parent 3d32fe95c5
commit 63fedc9db6
77 changed files with 2817 additions and 558 deletions

View File

@@ -0,0 +1,400 @@
/*
* 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.cachemap;
import java.util.*;
public class CacheMap implements Map
{
/*--------------------------------------------------------------------------------
* Internal class used to do comparisons for cache shrinkage
*--------------------------------------------------------------------------------
*/
static class CacheOrdering implements Comparator
{
private CacheMapStrategy strategy; // CacheMap's strategy object
private long tick; // when the sort operation started
CacheOrdering(CacheMapStrategy strategy)
{
this.strategy = strategy;
this.tick = System.currentTimeMillis();
} // end constructor
public int compare(Object o1, Object o2)
{
long figm1 = strategy.getEntryValue((CacheMapEntry)o1,tick);
long figm2 = strategy.getEntryValue((CacheMapEntry)o2,tick);
return (int)(figm1 - figm2); // we want the largest figures of merit to go first
} // end compare
public boolean equals(Object o)
{
return (o instanceof CacheOrdering);
} // end equals
} // end class CacheOrdering
/*--------------------------------------------------------------------------------
* Internal class implementing a default cache ordering strategy
*--------------------------------------------------------------------------------
*/
static class DefaultStrategy implements CacheMapStrategy
{
private static final long SCALING_FACTOR = 5000;
DefaultStrategy()
{ // do nothing
} // end constructor
public long getEntryValue(CacheMapEntry entry, long tick)
{
return (entry.getHits() * SCALING_FACTOR) - entry.getAge(tick);
} // end getEntryValue
} // end class DefaultStrategy
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final DefaultStrategy default_strategy_singleton = new DefaultStrategy();
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private int capacity; // capacity of the CacheMap
private int shrink_percentage; // what percentage we shrink by when full
private CacheMapStrategy strategy; // strategy routine to use to purge entries
private HashMap base_map; // maps keys to CacheMapEntry values
private ArrayList element_list; // the actual elements
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
public CacheMap(int capacity, int shrink_percentage, CacheMapStrategy strategy)
{
if (capacity<=0)
throw new IllegalArgumentException("capacity must be greater than 0");
if ((shrink_percentage<=0) || (shrink_percentage>100))
throw new IllegalArgumentException("shrink_percentage must be in [1, 100]");
if (strategy==null)
throw new NullPointerException("no strategy passed to CacheMap");
this.capacity = capacity;
this.shrink_percentage = shrink_percentage;
this.strategy = strategy;
this.base_map = new HashMap(10);
this.element_list = new ArrayList(10);
} // end constructor
public CacheMap(int capacity, int shrink_percentage)
{
this(capacity,shrink_percentage,default_strategy_singleton);
} // end constructor
public CacheMap(int capacity)
{
this(capacity,10,default_strategy_singleton);
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface Map
*--------------------------------------------------------------------------------
*/
public int size()
{
return base_map.size();
} // end size
public boolean isEmpty()
{
return base_map.isEmpty();
} // end isEmpty
public boolean containsKey(Object key)
{
return base_map.containsKey(key);
} // end containsKey
public boolean containsValue(Object value)
{
Iterator it = element_list.iterator();
while (it.hasNext())
{ // look at all the CacheMapEntry values we have
CacheMapEntry cme = (CacheMapEntry)(it.next());
Object my_val = cme.getValue();
if (my_val==null)
{ // test for also null
if (value==null)
return true;
} // end if
else
{ // make sure the other value is non-null before we test equality
if ((value!=null) && my_val.equals(value))
return true;
} // end else
} // end while
return false; // nope, sorry
} // end containsValue
public Object get(Object key)
{
CacheMapEntry cme = (CacheMapEntry)(base_map.get(key));
if (cme==null)
return null;
cme.touch();
return cme.getValue();
} // end get
public Object put(Object key, Object value)
{
Object rc = null;
CacheMapEntry cme = (CacheMapEntry)(base_map.get(key));
if (cme==null)
{ // create a new CacheMapEntry for this key
cme = new CacheMapEntry(key,value);
synchronized (this)
{ // insert it into the basic object
if (base_map.size()==capacity)
shrink();
element_list.add(cme);
base_map.put(cme.getKey(),cme);
} // end synchronized block
} // end if
else
{ // we have an old value - replace it and touch the entry
cme.touch();
rc = cme.setValue(value);
} // end else
return rc;
} // end put
public Object remove(Object key)
{
Object rc = null;
CacheMapEntry cme = (CacheMapEntry)(base_map.get(key));
if (cme!=null)
{ // save the mapped value before we remove it
rc = cme.getValue();
synchronized (this)
{ // remove the values
base_map.remove(key);
element_list.remove(cme);
} // end synchronized block
} // end if
return rc;
} // end remove
public void putAll(Map map)
{
synchronized (this)
{ // make sure we have enough space in the CacheMap for all the new elements!
while ((map.size() + base_map.size()) > capacity)
shrink();
} // end synchronized block
Iterator it = map.entrySet().iterator();
while (it.hasNext())
{ // add each element in turn
Map.Entry me = (Map.Entry)(it.next());
put(me.getKey(),me.getValue());
} // end while
} // end putAll
public synchronized void clear()
{
base_map.clear();
element_list.clear();
} // end clear
public Set keySet()
{
return base_map.keySet();
} // end keySet
public Collection values()
{
return null; // not implemented
} // end values
public Set entrySet()
{
return null; // not implemented
} // end entrySet
public boolean equals(Object o)
{
if ((o==null) || !(o instanceof Map))
return false; // not a map
Map other = (Map)o;
if (other.size()!=base_map.size())
return false; // size does matter!
Iterator it = base_map.values().iterator();
while (it.hasNext())
{ // get each of the entries out and use that to do a key-value comparison
CacheMapEntry cme = (CacheMapEntry)(it.next());
Object o1 = cme.getValue();
Object o2 = other.get(cme.getKey());
if (o1==null)
{ // must have a matching null
if (o2!=null)
return false;
} // end if
else
{ // make sure we have a matching object (not null)
if ((o2==null) || !(o2.equals(o1)))
return false;
} // end else
} // end while
return true; // all OK!
} // end equals
public int hashCode()
{
int rc = 0;
Iterator it = base_map.values().iterator();
while (it.hasNext())
{ // add up the hash codes and return them
CacheMapEntry cme = (CacheMapEntry)(it.next());
rc += cme.hashCode();
} // end while
return rc;
} // end hashCode
/*--------------------------------------------------------------------------------
* External getters/setters
*--------------------------------------------------------------------------------
*/
public int getCapacity()
{
return capacity;
} // end getCapacity
public void setCapacity(int c)
{
if (c<=0)
throw new IllegalArgumentException("capacity must be greater than 0");
capacity = c;
} // end setCapacity
public int getShrinkPercentage()
{
return shrink_percentage;
} // end getShrinkPercentage
public void setShrinkPercentage(int p)
{
if ((p<=0) || (p>100))
throw new IllegalArgumentException("shrink_percentage must be in [1, 100]");
shrink_percentage = p;
} // end setShrinkPercentage
public CacheMapStrategy getStrategy()
{
return strategy;
} // end getStrategy
public void setStrategy(CacheMapStrategy s)
{
if (s==null)
throw new NullPointerException("no strategy passed to CacheMap");
strategy = s;
} // end setStrategy
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public synchronized void shrink()
{
// Figure out how many elements to remove.
int num_remove = (element_list.size() * shrink_percentage) / 100;
// Sort the element list to figure out which elements to remove.
Collections.sort(element_list,new CacheOrdering(strategy));
// The elements we want to remove are at the end of the array, so start from there.
for (int i=0; i<num_remove; i++)
{ // remove the "removed" entries from the hash map
CacheMapEntry cme = (CacheMapEntry)(element_list.remove(element_list.size() - 1));
base_map.remove(cme.getKey());
} // end for
} // end shrink
} // end class CacheMap

View File

@@ -0,0 +1,154 @@
/*
* 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.cachemap;
import java.util.*;
class CacheMapEntry implements Map.Entry
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private Object key;
private Object value;
private int hits = 0;
private long timestamp;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
CacheMapEntry(Object key, Object value)
{
this.key = key;
this.value = value;
this.timestamp = System.currentTimeMillis();
} // end constructor
/*--------------------------------------------------------------------------------
* finalize() function
*--------------------------------------------------------------------------------
*/
protected void finalize()
{
key = null;
value = null;
} // end finalize
/*--------------------------------------------------------------------------------
* Implementations from interface MapEntry
*--------------------------------------------------------------------------------
*/
public final Object getKey()
{
return key;
} // end getKey
public final Object getValue()
{
return value;
} // end getValue
public final Object setValue(Object o)
{
Object rc = value;
value = o;
return rc;
} // end setValue
public final boolean equals(Object o)
{
// make sure the other element is a Map.Entry
if ((o==null) || !(o instanceof Map.Entry))
return false;
Map.Entry other = (Map.Entry)o;
// compare the keys
if (key==null)
{ // the other key must be null
if (other.getKey()!=null)
return false;
} // end if
else
{ // the other key must be equal to us
if ((other.getKey()==null) || (!(key.equals(other.getKey()))))
return false;
} // end else
// compare the values
if (value==null)
return (other.getValue()==null);
else
return ((other.getValue()!=null) && value.equals(other.getValue()));
} // end equals
public final int hashCode()
{
int rc = 0;
if (key!=null)
rc ^= key.hashCode();
if (value!=null)
rc ^= value.hashCode();
return rc;
} // end hashCode
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
final int getHits()
{
return hits;
} // end getHits
final long getTimestamp()
{
return timestamp;
} // end getTimestamp
final long getAge(long tick)
{
return (tick - timestamp);
} // end getAge
final void touch()
{
hits++;
timestamp = System.currentTimeMillis();
} // end touch
} // end class CacheMapEntry

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.cachemap;
public interface CacheMapStrategy
{
public abstract long getEntryValue(CacheMapEntry entry, long tick);
} // end interface CacheMapStrategy

View File

@@ -1,72 +0,0 @@
/*
* 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.collections;
import java.util.*;
public class ReadOnlyVector extends AbstractList
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private Vector my_vec; // local vector
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public ReadOnlyVector(Vector vec)
{
my_vec = vec;
my_vec.trimToSize();
} // end constructor
/*--------------------------------------------------------------------------------
* finalize() method
*--------------------------------------------------------------------------------
*/
protected void finalize() throws Throwable
{
my_vec = null;
super.finalize();
} // end finalize
/*--------------------------------------------------------------------------------
* Implementations from superclass AbstractList
*--------------------------------------------------------------------------------
*/
public Object get(int index)
{
return my_vec.elementAt(index);
} // end get
public int size()
{
return my_vec.size();
} // end size
} // end class ReadOnlyVector

View File

@@ -18,7 +18,6 @@
package com.silverwrist.util.rcache;
import java.util.*;
import com.silverwrist.util.collections.*;
public class ReferenceCache
{
@@ -124,7 +123,7 @@ public class ReferenceCache
public List sweepReturn()
{
Vector rc = new Vector();
ArrayList rc = new ArrayList();
int count = 0;
synchronized (this)
@@ -155,7 +154,7 @@ public class ReferenceCache
} // end synchronized block
return new ReadOnlyVector(rc);
return Collections.unmodifiableList(rc);
} // end sweepReturn