diff --git a/etc/render-config.xml b/etc/render-config.xml index 24a4642..2c2fb03 100644 --- a/etc/render-config.xml +++ b/etc/render-config.xml @@ -8,7 +8,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 @@ -86,4 +86,38 @@ Text of this agreement is TBD. + + + + + +
Front Page
+ + Calendar + TODO + + + + Chat + TODO + + +
+ + + +
About This Site
+ + Documentation + TODO + + + + About Venice + about-venice.html + +
+ +
+ diff --git a/etc/web.xml b/etc/web.xml index e9937ad..3c43bdc 100644 --- a/etc/web.xml +++ b/etc/web.xml @@ -69,6 +69,14 @@ 3 + + framestatic + + Displays static content inside the Venice frame. + + com.silverwrist.venice.servlets.FrameStatic + + account @@ -216,6 +224,11 @@ /top + + framestatic + /frame/* + + account /account diff --git a/setup/database.sql b/setup/database.sql index 4c432b9..8acd443 100644 --- a/setup/database.sql +++ b/setup/database.sql @@ -71,6 +71,7 @@ CREATE TABLE users ( uid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, username VARCHAR(64) NOT NULL, passhash VARCHAR(64) NOT NULL, + tokenauth VARCHAR(64), contactid INT DEFAULT -1, is_anon TINYINT DEFAULT 0, verify_email TINYINT DEFAULT 0, @@ -345,6 +346,8 @@ CREATE TABLE topicsettings ( uid INT NOT NULL, hidden TINYINT DEFAULT 0, last_message INT DEFAULT -1, + last_read DATETIME, + last_post DATETIME, PRIMARY KEY (topicid, uid) ); diff --git a/src/com/silverwrist/util/cachemap/CacheMap.java b/src/com/silverwrist/util/cachemap/CacheMap.java new file mode 100644 index 0000000..7aea300 --- /dev/null +++ b/src/com/silverwrist/util/cachemap/CacheMap.java @@ -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 . + * + * 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.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. + * + * 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.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 diff --git a/src/com/silverwrist/venice/servlets/format/MenuTop.java b/src/com/silverwrist/util/cachemap/CacheMapStrategy.java similarity index 60% rename from src/com/silverwrist/venice/servlets/format/MenuTop.java rename to src/com/silverwrist/util/cachemap/CacheMapStrategy.java index e8c2fe2..10f1e33 100644 --- a/src/com/silverwrist/venice/servlets/format/MenuTop.java +++ b/src/com/silverwrist/util/cachemap/CacheMapStrategy.java @@ -15,23 +15,10 @@ * * Contributor(s): */ -package com.silverwrist.venice.servlets.format; +package com.silverwrist.util.cachemap; -import java.io.Writer; -import java.io.IOException; - -public class MenuTop implements ComponentRender +public interface CacheMapStrategy { - public MenuTop() - { // constructor does nothing - } // end constructor + public abstract long getEntryValue(CacheMapEntry entry, long tick); - public void renderHere(Writer out, RenderData rdat) throws IOException - { - out.write("Front Page
\n"); - out.write("Calendar
\n"); // TODO: fill this link in - out.write("Chat\n"); // TODO: fill this link in - - } // end renderHere - -} // end class MenuTop +} // end interface CacheMapStrategy diff --git a/src/com/silverwrist/util/rcache/ReferenceCache.java b/src/com/silverwrist/util/rcache/ReferenceCache.java index ebc12cc..e310428 100644 --- a/src/com/silverwrist/util/rcache/ReferenceCache.java +++ b/src/com/silverwrist/util/rcache/ReferenceCache.java @@ -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 diff --git a/src/com/silverwrist/venice/core/TopicContext.java b/src/com/silverwrist/venice/core/TopicContext.java index 2a8f528..3a15113 100644 --- a/src/com/silverwrist/venice/core/TopicContext.java +++ b/src/com/silverwrist/venice/core/TopicContext.java @@ -78,5 +78,17 @@ public interface TopicContext public abstract void delete() throws DataException, AccessError; + public abstract List getActivePosters(int skip, int limit) throws DataException, AccessError; + + public abstract List getActivePosters(int limit) throws DataException, AccessError; + + public abstract List getActivePosters() throws DataException, AccessError; + + public abstract List getActiveReaders(int skip, int limit) throws DataException, AccessError; + + public abstract List getActiveReaders(int limit) throws DataException, AccessError; + + public abstract List getActiveReaders() throws DataException, AccessError; + } // end interface TopicContext diff --git a/src/com/silverwrist/venice/core/UserContext.java b/src/com/silverwrist/venice/core/UserContext.java index fb08fe7..9330426 100644 --- a/src/com/silverwrist/venice/core/UserContext.java +++ b/src/com/silverwrist/venice/core/UserContext.java @@ -103,4 +103,8 @@ public interface UserContext extends SearchMode public abstract void setTimeZone(TimeZone timezone) throws DataException; + public abstract String getAuthenticationToken() throws AccessError, DataException; + + public abstract boolean authenticateWithToken(String token) throws DataException; + } // end interface UserContext diff --git a/src/com/silverwrist/venice/core/impl/CategoryDescriptorImpl.java b/src/com/silverwrist/venice/core/impl/CategoryDescriptorImpl.java index 2d68dbb..452caee 100644 --- a/src/com/silverwrist/venice/core/impl/CategoryDescriptorImpl.java +++ b/src/com/silverwrist/venice/core/impl/CategoryDescriptorImpl.java @@ -20,7 +20,6 @@ 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.*; @@ -70,7 +69,7 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable */ private DataPool datapool; // used for doing database lookups - private Vector cats; // the actual category segments + private LinkedList cats; // the actual category segments private int symlink = -1; // if our category is actually a symlink private boolean do_hide = true; // do we hide subcategories marked hide_dir? @@ -82,7 +81,7 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable CategoryDescriptorImpl(DataPool datapool, int catid, boolean do_hide) throws DataException { this.datapool = datapool; - cats = new Vector(); + cats = new LinkedList(); this.do_hide = do_hide; if (catid<0) @@ -114,7 +113,7 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable throws SQLException, DataException { this.datapool = datapool; - cats = new Vector(); + cats = new LinkedList(); this.do_hide = do_hide; if (catid<0) @@ -127,19 +126,18 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable protected CategoryDescriptorImpl(DataPool datapool, int id, int symlink, String name, boolean do_hide) { this.datapool = datapool; - this.cats = new Vector(); + this.cats = new LinkedList(); this.symlink = symlink; this.do_hide = do_hide; this.cats.add(new CatSegment(id,name)); - this.cats.trimToSize(); } // end constructor protected CategoryDescriptorImpl(CategoryDescriptorImpl other, int copy_levels) { this.datapool = other.datapool; - this.cats = new Vector(); + this.cats = new LinkedList(); this.symlink = ((copy_levels==other.cats.size()) ? other.symlink : -1); this.do_hide = other.do_hide; @@ -147,7 +145,6 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable { // copy the references to the objects directly for (int i=0; i0) - return ((CatSegment)(cats.lastElement())).getID(); + return ((CatSegment)(cats.getLast())).getID(); else return -1; @@ -260,7 +254,7 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable } // end if Connection conn = null; - Vector rc = new Vector(); + ArrayList rc = new ArrayList(); try { // get a connection and create a statement conn = datapool.getConnection(); @@ -294,8 +288,7 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable } // end finally - // wrap the vector in a ReadOnlyVector object - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getSubCategories @@ -393,7 +386,7 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable static List getTopLevelCategoryList(DataPool datapool, boolean do_hide) throws DataException { Connection conn = null; - Vector rc = new Vector(); + ArrayList rc = new ArrayList(); try { // get a connection and create a statement conn = datapool.getConnection(); @@ -426,8 +419,7 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable } // end finally - // wrap the vector in a ReadOnlyVector object - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getTopLevelCategoryList @@ -438,7 +430,7 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable logger.debug("Category search: mode = " + String.valueOf(mode) + ", term '" + term + "', offset = " + String.valueOf(offset) + ", count = " + String.valueOf(count)); - Vector rc = new Vector(); + ArrayList rc = new ArrayList(); Connection conn = null; // pooled database connection try @@ -505,7 +497,7 @@ class CategoryDescriptorImpl implements CategoryDescriptor, Cloneable } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end searchForCategories diff --git a/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java b/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java index e7b256f..b6ebdc1 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java @@ -20,7 +20,6 @@ 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; @@ -233,7 +232,7 @@ class ConferenceCoreData implements ConferenceData throw new DataException("This conference has been deleted."); Connection conn = null; - Vector rc = new Vector(); + ArrayList rc = new ArrayList(); try { // get a database connection from this object @@ -263,7 +262,7 @@ class ConferenceCoreData implements ConferenceData } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getAlias @@ -273,7 +272,7 @@ class ConferenceCoreData implements ConferenceData throw new DataException("This conference has been deleted."); Connection conn = null; - Vector rc = new Vector(); + ArrayList rc = new ArrayList(); try { // get a database connection from this object @@ -312,7 +311,7 @@ class ConferenceCoreData implements ConferenceData } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getHosts @@ -1059,7 +1058,7 @@ class ConferenceCoreData implements ConferenceData if (logger.isDebugEnabled()) logger.debug("Member list: conference = " + confid); - Vector rc = new Vector(); // return from this function + ArrayList rc = new ArrayList(); // return from this function Connection conn = null; // pooled database connection try @@ -1104,7 +1103,7 @@ class ConferenceCoreData implements ConferenceData } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getMemberList diff --git a/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java b/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java index e6a3570..9e775c6 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java @@ -20,7 +20,6 @@ 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.*; @@ -95,19 +94,21 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend } // end constructor - public void doFix(Statement stmt, int uid) throws SQLException + public void doFix(Statement stmt, int uid, java.util.Date date) throws SQLException { StringBuffer sql = new StringBuffer(); if (do_insert) { // construct an SQL INSERT statement - sql.append("INSERT INTO topicsettings (topicid, uid, last_message) VALUES (").append(topicid); - sql.append(", ").append(uid).append(", ").append(top_message).append(");"); + sql.append("INSERT INTO topicsettings (topicid, uid, last_message, last_read) VALUES ("); + sql.append(topicid).append(", ").append(uid).append(", ").append(top_message).append(", '"); + sql.append(SQLUtil.encodeDate(date)).append("');"); } // end if else { // construct an SQL UPDATE statement - sql.append("UPDATE topicsettings SET last_message = ").append(top_message).append(" WHERE topicid = "); - sql.append(topicid).append(" AND uid = ").append(uid).append(';'); + sql.append("UPDATE topicsettings SET last_message = ").append(top_message).append(", last_read = '"); + sql.append(SQLUtil.encodeDate(date)).append("' WHERE topicid = ").append(topicid); + sql.append(" AND uid = ").append(uid).append(';'); } // end else @@ -941,8 +942,17 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend // now we need to reset our last post date Connection conn = null; try - { // get a connection and feed it to the touchPost function + { // get a connection conn = datapool.getConnection(); + + // create a new record in topicsettings (we WERE the first to post in the topic after all!) + Statement stmt = conn.createStatement(); + StringBuffer sql = new StringBuffer("INSERT INTO topicsettings (topicid, uid, last_post) VALUES ("); + sql.append(new_topic_inf.getTopicID()).append(", ").append(sig.realUID()).append(", '"); + sql.append(SQLUtil.encodeDate(new_topic_inf.getCreateDate())).append("');"); + stmt.executeUpdate(sql.toString()); + + // update the conference last-post information touchPost(conn,new_topic_inf.getCreateDate()); } // end try @@ -1024,16 +1034,17 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend ResultSet rs = stmt.executeQuery(sql.toString()); // use the results to build up a list of FixSeenHelpers - Vector tmp = new Vector(); + ArrayList tmp = new ArrayList(); while (rs.next()) tmp.add(new FixSeenHelper(rs.getInt(1),rs.getInt(2),rs.getBoolean(3))); // now iterate over the list and call doFix on each one Iterator it = tmp.iterator(); + java.util.Date now = new java.util.Date(); while (it.hasNext()) { // just hit each one in turn FixSeenHelper fsh = (FixSeenHelper)(it.next()); - fsh.doFix(stmt,sig.realUID()); + fsh.doFix(stmt,sig.realUID(),now); } // end while @@ -1074,7 +1085,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend } // end if Connection conn = null; - Vector rc = new Vector(); + ArrayList rc = new ArrayList(); try { // retrieve a connection from the datapool @@ -1115,7 +1126,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getActivePosters @@ -1141,7 +1152,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend } // end if Connection conn = null; - Vector rc = new Vector(); + ArrayList rc = new ArrayList(); try { // retrieve a connection from the datapool @@ -1182,7 +1193,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getActiveReaders @@ -1700,7 +1711,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend { if (logger.isDebugEnabled()) logger.debug("getSIGConferences for SIG # " + sig.realSIGID() + ", user #" + sig.realUID()); - Vector rc = new Vector(); // return from this function + ArrayList rc = new ArrayList(); // return from this function Connection conn = null; // pooled database connection try @@ -1751,7 +1762,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getSIGConferences @@ -1863,7 +1874,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend logger.debug("getUserHotlist for user #" + user.realUID()); Connection conn = null; // pooled database connection - Vector rc = new Vector(); // return from this function + ArrayList rc = new ArrayList(); // return from this function try { // get a database connection @@ -1926,7 +1937,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getUserHotlist diff --git a/src/com/silverwrist/venice/core/impl/EngineBackend.java b/src/com/silverwrist/venice/core/impl/EngineBackend.java index c0bad70..80a344c 100644 --- a/src/com/silverwrist/venice/core/impl/EngineBackend.java +++ b/src/com/silverwrist/venice/core/impl/EngineBackend.java @@ -93,4 +93,8 @@ public interface EngineBackend public abstract void unpublish(long postid); + public abstract String generateRandomAuthString(); + + public abstract boolean isValidRandomAuthString(String s); + } // end interface EngineBackend diff --git a/src/com/silverwrist/venice/core/impl/SIGCoreData.java b/src/com/silverwrist/venice/core/impl/SIGCoreData.java index 7e177c6..a60a29b 100644 --- a/src/com/silverwrist/venice/core/impl/SIGCoreData.java +++ b/src/com/silverwrist/venice/core/impl/SIGCoreData.java @@ -21,7 +21,6 @@ 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.*; @@ -1493,7 +1492,7 @@ class SIGCoreData implements SIGData, SIGDataBackend logger.debug("Member search: SIG = " + sigid + ", field = " + field + ", mode = " + mode + ", term '" + term + "', offset = " + offset + ", count = " + count); - Vector rc = new Vector(); // return from this function + ArrayList rc = new ArrayList(); // return from this function Connection conn = null; // pooled database connection try @@ -1584,7 +1583,7 @@ class SIGCoreData implements SIGData, SIGDataBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end searchForMembers @@ -1689,7 +1688,7 @@ class SIGCoreData implements SIGData, SIGDataBackend if (logger.isDebugEnabled()) logger.debug("Member list: SIG = " + sigid); - Vector rc = new Vector(); // return from this function + ArrayList rc = new ArrayList(); // return from this function Connection conn = null; // pooled database connection try @@ -1737,7 +1736,7 @@ class SIGCoreData implements SIGData, SIGDataBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getMemberList diff --git a/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java b/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java index 102af25..11777be 100644 --- a/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/SIGUserContextImpl.java @@ -21,7 +21,6 @@ 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; @@ -163,7 +162,7 @@ class SIGUserContextImpl implements SIGContext, SIGBackend { if (logger.isDebugEnabled()) logger.debug("setMemberValues(" + String.valueOf(granted_level) + ", " + String.valueOf(member) - + ", " + String.valueOf(locked)); + + ", " + String.valueOf(locked) + ")"); if (user.realBaseLevel()>granted_level) this.level = user.realBaseLevel(); @@ -1484,7 +1483,7 @@ class SIGUserContextImpl implements SIGContext, SIGBackend { if (logger.isDebugEnabled()) logger.debug("getMemberSIGEntries for user #" + String.valueOf(user.realUID())); - Vector rc = new Vector(); // return from this function + ArrayList rc = new ArrayList(); // return from this function Connection conn = null; // pooled database connection try @@ -1521,7 +1520,7 @@ class SIGUserContextImpl implements SIGContext, SIGBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getMemberSIGEntries @@ -1611,7 +1610,7 @@ class SIGUserContextImpl implements SIGContext, SIGBackend + ", term '" + term + "', offset = " + String.valueOf(offset) + ", count = " + String.valueOf(count)); - Vector rc = new Vector(); // return from this function + ArrayList rc = new ArrayList(); // return from this function Connection conn = null; // pooled database connection try @@ -1688,7 +1687,7 @@ class SIGUserContextImpl implements SIGContext, SIGBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end searchForSIGs @@ -1780,7 +1779,7 @@ class SIGUserContextImpl implements SIGContext, SIGBackend logger.debug("reading SIGs in category " + String.valueOf(catid) + ", offset = " + String.valueOf(offset) + ", count = " + String.valueOf(count)); - Vector rc = new Vector(); // return from this function + ArrayList rc = new ArrayList(); // return from this function Connection conn = null; // pooled database connection try @@ -1823,7 +1822,7 @@ class SIGUserContextImpl implements SIGContext, SIGBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getSIGsInCategory diff --git a/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java b/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java index 717aad1..88b50c6 100644 --- a/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/TopicMessageUserContextImpl.java @@ -23,7 +23,6 @@ import java.util.*; import java.util.zip.*; 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; @@ -1092,7 +1091,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext logger.debug("loadMessageRange for conf # " + conf.realConfID() + ", topic #" + topicid + ", range [" + post_low + ", " + post_high + "]"); - Vector rc = new Vector(); + ArrayList rc = new ArrayList(); Connection conn = null; // pooled database connection try @@ -1138,7 +1137,7 @@ class TopicMessageUserContextImpl implements TopicMessageContext } // end finally - return new ReadOnlyVector(rc); // wrap the return vector + return Collections.unmodifiableList(rc); // wrap the return vector } // end loadMessageRange diff --git a/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java b/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java index 1e421f8..f9f1601 100644 --- a/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java @@ -20,7 +20,6 @@ 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; @@ -511,7 +510,9 @@ class TopicUserContextImpl implements TopicContext try { // start by trying to see if we can update topicsettings directly StringBuffer sql = new StringBuffer("UPDATE topicsettings SET last_message = "); - sql.append(last_msg).append(" WHERE topicid = ").append(topicid).append(" AND uid = "); + sql.append(last_msg).append(", last_read = '"); + java.util.Date now = new java.util.Date(); + sql.append(SQLUtil.encodeDate(now)).append("' WHERE topicid = ").append(topicid).append(" AND uid = "); sql.append(conf.realUID()).append(';'); if (logger.isDebugEnabled()) logger.debug("SQL: " + sql.toString()); @@ -540,8 +541,9 @@ class TopicUserContextImpl implements TopicContext // OK, just insert a new row into topicsettings, why dontcha... sql.setLength(0); - sql.append("INSERT INTO topicsettings (topicid, uid, last_message) VALUES (").append(topicid); - sql.append(", ").append(conf.realUID()).append(", ").append(last_msg).append(");"); + sql.append("INSERT INTO topicsettings (topicid, uid, last_message, last_read) VALUES ("); + sql.append(topicid).append(", ").append(conf.realUID()).append(", ").append(last_msg).append(", '"); + sql.append(SQLUtil.encodeDate(now)).append("');"); if (logger.isDebugEnabled()) logger.debug("SQL: " + sql.toString()); stmt.executeUpdate(sql.toString()); @@ -691,7 +693,7 @@ class TopicUserContextImpl implements TopicContext // slap a lock on all the tables we need to touch stmt.executeUpdate("LOCK TABLES confs WRITE, topics WRITE, posts WRITE, postdata WRITE, " - + "confsettings WRITE, topicsettings READ;"); + + "confsettings WRITE, topicsettings WRITE;"); try { // refresh our current status and recheck allowed status @@ -755,6 +757,25 @@ class TopicUserContextImpl implements TopicContext sql.append(real_text).append("');"); stmt.executeUpdate(sql.toString()); + // mark that we posted to the topic + sql.setLength(0); + sql.append("UPDATE topicsettings SET last_post = '").append(SQLUtil.encodeDate(posted_date)); + sql.append("' WHERE topicid = ").append(topicid).append(" AND uid = ").append(conf.realUID()); + sql.append(';'); + if (logger.isDebugEnabled()) + logger.debug("SQL: " + sql.toString()); + if (stmt.executeUpdate(sql.toString())<1) + { // we had no topicsettings record, add one + sql.setLength(0); + sql.append("INSERT INTO topicsettings (topicid, uid, last_post) VALUES (").append(topicid); + sql.append(", ").append(conf.realUID()).append(", '").append(SQLUtil.encodeDate(posted_date)); + sql.append("');"); + if (logger.isDebugEnabled()) + logger.debug("SQL: " + sql.toString()); + stmt.executeUpdate(sql.toString()); + + } // end if + // mark that we posted to the conference conf.touchUpdate(conn,posted_date); conf.touchPost(conn,posted_date); @@ -925,6 +946,126 @@ class TopicUserContextImpl implements TopicContext } // end delete + public List getActivePosters(int skip, int limit) throws DataException + { + Connection conn = null; + ArrayList rc = new ArrayList(); + + try + { // retrieve a connection from the datapool + conn = datapool.getConnection(); + Statement stmt = conn.createStatement(); + + // create the SQL statement to retrieve all posters + StringBuffer sql = + new StringBuffer("SELECT s.uid, u.username, s.last_read, s.last_post FROM topicsettings s, " + + "users u WHERE u.uid = s.uid AND s.topicid = "); + sql.append(topicid).append(" AND u.is_anon = 0 AND ISNULL(s.last_post) = 0 ORDER BY s.last_post DESC"); + if ((skip>=0) && (limit>0)) + sql.append(" LIMIT ").append(skip).append(", ").append(limit); + sql.append(';'); + + // execute the statement + ResultSet rs = stmt.executeQuery(sql.toString()); + + while (rs.next()) + { // return all the records as ActiveUser data elements + ActiveUser usr = new ActiveUserImpl(rs.getInt(1),rs.getString(2),SQLUtil.getFullDateTime(rs,3), + SQLUtil.getFullDateTime(rs,4)); + rc.add(usr); + + } // end while + + } // end try + catch (SQLException e) + { // this becomes a DataException + logger.error("DB error getting active poster list: " + e.getMessage(),e); + throw new DataException("unable to get active poster listing: " + e.getMessage(),e); + + } // end catch + finally + { // make sure we release the connection before we go + if (conn!=null) + datapool.releaseConnection(conn); + + } // end finally + + return Collections.unmodifiableList(rc); + + } // end getActivePosters + + public List getActivePosters(int limit) throws DataException, AccessError + { + return getActivePosters(0,limit); + + } // end getActivePosters + + public List getActivePosters() throws DataException, AccessError + { + return getActivePosters(-1,-1); + + } // end getActivePosters + + public List getActiveReaders(int skip, int limit) throws DataException, AccessError + { + Connection conn = null; + ArrayList rc = new ArrayList(); + + try + { // retrieve a connection from the datapool + conn = datapool.getConnection(); + Statement stmt = conn.createStatement(); + + // create the SQL statement to retrieve all readers + StringBuffer sql = + new StringBuffer("SELECT s.uid, u.username, s.last_read, s.last_post FROM topicsettings s, " + + "users u WHERE u.uid = s.uid AND s.topicid = "); + sql.append(topicid).append(" AND u.is_anon = 0 AND ISNULL(s.last_read) = 0 ORDER BY s.last_read DESC"); + if ((skip>=0) && (limit>0)) + sql.append(" LIMIT ").append(skip).append(", ").append(limit); + sql.append(';'); + + // execute the statement + ResultSet rs = stmt.executeQuery(sql.toString()); + + while (rs.next()) + { // return all the records as ActiveUser data elements + ActiveUser usr = new ActiveUserImpl(rs.getInt(1),rs.getString(2),SQLUtil.getFullDateTime(rs,3), + SQLUtil.getFullDateTime(rs,4)); + rc.add(usr); + + } // end while + + } // end try + catch (SQLException e) + { // this becomes a DataException + logger.error("DB error getting active reader list: " + e.getMessage(),e); + throw new DataException("unable to get active reader listing: " + e.getMessage(),e); + + } // end catch + finally + { // make sure we release the connection before we go + if (conn!=null) + datapool.releaseConnection(conn); + + } // end finally + + return Collections.unmodifiableList(rc); + + } // end getActiveReaders + + public List getActiveReaders(int limit) throws DataException, AccessError + { + return getActiveReaders(0,limit); + + } // end getActiveReaders + + public List getActiveReaders() throws DataException, AccessError + { + return getActiveReaders(-1,-1); + + } // end getActiveReaders + /*-------------------------------------------------------------------------------- * External operations usable only from within the package *-------------------------------------------------------------------------------- @@ -936,7 +1077,7 @@ class TopicUserContextImpl implements TopicContext if (logger.isDebugEnabled()) logger.debug("getTopicList for conf # " + String.valueOf(conf.realConfID()) + ", user #" + String.valueOf(conf.realUID())); - Vector rc = new Vector(); // return from this function + ArrayList rc = new ArrayList(); // return from this function Connection conn = null; // pooled database connection try @@ -1088,7 +1229,7 @@ class TopicUserContextImpl implements TopicContext } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getTopicList diff --git a/src/com/silverwrist/venice/core/impl/UserContextImpl.java b/src/com/silverwrist/venice/core/impl/UserContextImpl.java index de536b2..c803a3f 100644 --- a/src/com/silverwrist/venice/core/impl/UserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/UserContextImpl.java @@ -22,7 +22,6 @@ 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.*; @@ -41,6 +40,9 @@ class UserContextImpl implements UserContext, UserBackend private static Category logger = Category.getInstance(UserContextImpl.class.getName()); + private static final String AUTH_TOKEN_PREFIX = "VQAT:"; + private static final char AUTH_TOKEN_SEP = '|'; + /*-------------------------------------------------------------------------------- * Attributes *-------------------------------------------------------------------------------- @@ -902,7 +904,7 @@ class UserContextImpl implements UserContext, UserBackend public List getSideBoxList() throws DataException { Connection conn = null; - Vector rc = new Vector(); + ArrayList rc = new ArrayList(); try { // retrieve a connection from the data pool @@ -934,7 +936,7 @@ class UserContextImpl implements UserContext, UserBackend } // end finally - return new ReadOnlyVector(rc); + return Collections.unmodifiableList(rc); } // end getSideBoxList @@ -1052,6 +1054,235 @@ class UserContextImpl implements UserContext, UserBackend } // end setTimeZone + public String getAuthenticationToken() throws AccessError, DataException + { + if (!isLoggedIn()) + { // can't generate an authentication token if we're not authenticated! + logger.error("UserContext not authenticated, cannot generate auth token"); + throw new AccessError("You cannot generate an authentication token without logging in."); + + } // end if + + // Generate a random authentication string and poke it into the database for this user. + String tokenauth = engine.generateRandomAuthString(); + Connection conn = null; + + try + { // retrieve a connection from the data pool + conn = datapool.getConnection(); + Statement stmt = conn.createStatement(); + StringBuffer sql = new StringBuffer("UPDATE users SET tokenauth = '"); + sql.append(tokenauth).append("' WHERE uid = ").append(uid).append(';'); + stmt.executeUpdate(sql.toString()); + + } // end try + catch (SQLException e) + { // turn SQLException into data exception + logger.error("DB error setting token authentication string: " + e.getMessage(),e); + throw new DataException("Unable to set authentication token: " + e.getMessage(),e); + + } // end catch + finally + { // make sure the connection is released before we go + if (conn!=null) + datapool.releaseConnection(conn); + + } // end finally + + // Build the full authentication token string value. + int checkvalue = uid ^ tokenauth.hashCode(); + StringBuffer buf = new StringBuffer(AUTH_TOKEN_PREFIX); + buf.append(uid).append(AUTH_TOKEN_SEP).append(tokenauth).append(AUTH_TOKEN_SEP).append(checkvalue); + buf.append(AUTH_TOKEN_SEP); + return buf.toString(); + + } // end getAuthenticationToken + + public boolean authenticateWithToken(String token) throws DataException + { + if (isLoggedIn()) + { // already authenticated, can't authenticate again + logger.error("UserContext already authenticated (with uid " + uid + ")"); + throw new InternalStateError("context already authenticated"); + + } // end if + + if (logger.isDebugEnabled()) + logger.debug("decoding authtoken: " + token); + + // Pick apart the authentication token value. + if (!(token.startsWith(AUTH_TOKEN_PREFIX))) + { // token parse error + logger.error("Token parse error: prefix not valid"); + return false; + + } // end if + + int xstart = AUTH_TOKEN_PREFIX.length(); + int xend = token.indexOf(AUTH_TOKEN_SEP,xstart); + if (xend<0) + { // could not find the UID separator + logger.error("Token parse error: UID sep not found"); + return false; + + } // end if + + int pending_uid; + try + { // get the user ID + pending_uid = Integer.parseInt(token.substring(xstart,xend)); + + } // end try + catch (NumberFormatException nfe) + { // we couldn't parse the UID + logger.error("Token parse error: invalid UID value"); + return false; + + } // end catch + + xstart = xend + 1; + xend = token.indexOf(AUTH_TOKEN_SEP,xstart); + if (xend<0) + { // could not find the auth string separator + logger.error("Token parse error: auth string sep not found"); + return false; + + } // end if + + String pending_auth = token.substring(xstart,xend); + if (!(engine.isValidRandomAuthString(pending_auth))) + { // the auth string is not valid by the rules under which it was generated + logger.error("Token parse error: invalid auth string value"); + return false; + + } // end if + + xstart = xend + 1; + xend = token.indexOf(AUTH_TOKEN_SEP,xstart); + if (xend<0) + { // could not find the checkvalue separator + logger.error("Token parse error: checkvalue sep not found"); + return false; + + } // end if + + int checkvalue; + try + { // get the check value + checkvalue = Integer.parseInt(token.substring(xstart,xend)); + + } // end try + catch (NumberFormatException nfe) + { // we couldn't parse the checkvalue + logger.error("Token parse error: invalid checkvalue"); + return false; + + } // end catch + + if (checkvalue!=(pending_uid ^ pending_auth.hashCode())) + { // the checkvalue does not match what it should - possible corrupted token + logger.error("Token parse error: checkvalue does not match"); + return false; + + } // end if + + // At this point, we now have a UID and authentication string extracted from the token. + // Proceed to authenticate. + if (logger.isDebugEnabled()) + logger.debug("Authenticating user ID#" + pending_uid); + + Connection conn = null; + AuditRecord ar = null; + + try + { // look for a user record matching this user ID + conn = datapool.getConnection(); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM users WHERE uid = " + pending_uid + ";"); + + if (!(rs.next())) + { // user not found + logger.error("...user not found"); + ar = new AuditRecord(AuditRecord.LOGIN_FAIL,0,remote_addr,"Bad token UID: " + pending_uid); + return false; + + } // end if + + if (rs.getBoolean("is_anon")) + { // can't log in as Anonymous Honyak + logger.error("...user is the Anonymous Honyak, can't explicitly login"); + ar = new AuditRecord(AuditRecord.LOGIN_FAIL,pending_uid,remote_addr,"Anonymous user"); + return false; + + } // end if + + if (rs.getBoolean("lockout")) + { // account locked out + logger.error("...user is locked out by the Admin"); + ar = new AuditRecord(AuditRecord.LOGIN_FAIL,pending_uid,remote_addr,"Account locked out"); + return false; + + } // end if + + // compare the stored token auth value to what we have + if (!(pending_auth.equals(rs.getString("tokenauth")))) + { // the auth string is bad - we can't log in + logger.warn("...invalid authentication string"); + ar = new AuditRecord(AuditRecord.LOGIN_FAIL,pending_uid,remote_addr,"Bad auth-string"); + return false; + + } // end if + + if (logger.isDebugEnabled()) + logger.debug("...authenticated"); + + // we're authenticated - load the user data into the context + loadUserData(rs); + + // update the "last access" time in the database + java.util.Date mydate = new java.util.Date(); + stmt.executeUpdate("UPDATE users SET lastaccess = '" + SQLUtil.encodeDate(mydate) + + "' WHERE uid = " + uid + ";"); + + // update the "last access" time in this object + last_access = mydate; + + // an audit record indicating we logged in OK + ar = new AuditRecord(AuditRecord.LOGIN_OK,uid,remote_addr); + + if (logger.isDebugEnabled()) + logger.debug("...context loaded, we're ready :-)"); + + } // end try + catch (SQLException e) + { // database error - this is a DataException + logger.error("DB error reading user data: " + e.getMessage(),e); + throw new DataException("unable to access user data: " + e.getMessage(),e); + + } // end catch + finally + { // make sure the connection is released before we go + try + { // save off the audit record before we go, though + if ((ar!=null) && (conn!=null)) + ar.store(conn); + + } // end try + catch (SQLException e) + { // we couldn't store the audit record! + logger.error("DB error saving audit record: " + e.getMessage(),e); + + } // end catch + + if (conn!=null) + datapool.releaseConnection(conn); + + } // end if + + return true; // token authentication worked! + + } // end authenticateWithToken + /*-------------------------------------------------------------------------------- * Implementations from interface UserBackend *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java index ff4d6ab..24997bd 100644 --- a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java +++ b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java @@ -23,7 +23,6 @@ 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.*; @@ -385,6 +384,10 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend private static Category logger = Category.getInstance(VeniceEngineImpl.class.getName()); + private static final String AUTH_ALPHABET = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"; + private static final int AUTH_STRING_LEN = 32; + /*-------------------------------------------------------------------------------- * Attributes *-------------------------------------------------------------------------------- @@ -406,7 +409,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend private int[] gp_ints; // global integer parameters private MasterSideBox[] sideboxes; // master sidebox table private Hashtable sidebox_ids = new Hashtable(); // maps sidebox IDs to MasterSideBox objects - private Vector cache_fp_posts = new Vector(); // all posts that have been published to front page + private LinkedList cache_fp_posts = new LinkedList(); // all posts that have been published to front page private boolean cache_fp_posts_busy = false; // busy flag for above vector /*-------------------------------------------------------------------------------- @@ -482,7 +485,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend this.config = config; - Vector dictionary_tmp; + ArrayList dictionary_tmp; try { // first, verify that this is a valid configuration Element root = config.getDocumentElement(); @@ -542,7 +545,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend } // end if // Retrieve the list of dictionary files to load into the spellchecker. - dictionary_tmp = new Vector(); + dictionary_tmp = new ArrayList(); NodeList dict_nodes = dict_sect.getChildNodes(); for (i=0; i element looking for elements @@ -625,15 +628,13 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend logger.debug(max_value + " features loaded from database"); // load the master sidebox table - Vector sidebox_tmp = new Vector(); + ArrayList sidebox_tmp = new ArrayList(); rs = stmt.executeQuery("SELECT * FROM refsidebox ORDER BY boxid;"); while (rs.next()) sidebox_tmp.add(new MasterSideBox(rs)); // store the real master sidebox table as an array - sideboxes = new MasterSideBox[sidebox_tmp.size()]; - for (i=0; igp_ints[IP_NUMFRONTPAGEPOSTS]) - cache_fp_posts.remove(cache_fp_posts.size()-1); + cache_fp_posts.removeLast(); } // end pubmsg @@ -1962,4 +1960,28 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend } // end unpublish + public String generateRandomAuthString() + { + StringBuffer buf = new StringBuffer(AUTH_STRING_LEN); + 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.venice.servlets; + +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; +import org.apache.log4j.*; +import com.silverwrist.venice.core.*; +import com.silverwrist.venice.servlets.format.*; + +public class FrameStatic extends VeniceServlet +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Category logger = Category.getInstance(FrameStatic.class); + + /*-------------------------------------------------------------------------------- + * Overrides from class HttpServlet + *-------------------------------------------------------------------------------- + */ + + public String getServletInfo() + { + String rc = "FrameStatic servlet - Displays a static page inside the Venice \"frame\"\n" + + "Part of the Venice Web Communities System\n"; + return rc; + + } // end getServletInfo + + /*-------------------------------------------------------------------------------- + * Overrides from class VeniceServlet + *-------------------------------------------------------------------------------- + */ + + protected VeniceContent doVeniceGet(HttpServletRequest request, VeniceEngine engine, + UserContext user, RenderData rdat) + throws ServletException, IOException, VeniceServletResult + { + setMyLocation(request,"frame" + request.getPathInfo()); + return StaticRender.getStaticRender(request.getPathInfo().substring(1)); + + } // end doVeniceGet + +} // end class FrameStatic diff --git a/src/com/silverwrist/venice/servlets/UserDisplay.java b/src/com/silverwrist/venice/servlets/UserDisplay.java index ea0c8b2..fc2fc19 100644 --- a/src/com/silverwrist/venice/servlets/UserDisplay.java +++ b/src/com/silverwrist/venice/servlets/UserDisplay.java @@ -31,7 +31,7 @@ public class UserDisplay extends VeniceServlet *-------------------------------------------------------------------------------- */ - private static Category logger = Category.getInstance(UserDisplay.class.getName()); + private static Category logger = Category.getInstance(UserDisplay.class); /*-------------------------------------------------------------------------------- * Overrides from class HttpServlet diff --git a/src/com/silverwrist/venice/servlets/Variables.java b/src/com/silverwrist/venice/servlets/Variables.java index 4b64693..6f18b67 100644 --- a/src/com/silverwrist/venice/servlets/Variables.java +++ b/src/com/silverwrist/venice/servlets/Variables.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 @@ -23,6 +23,7 @@ import javax.servlet.http.*; import org.apache.log4j.*; import com.silverwrist.venice.core.*; import com.silverwrist.venice.servlets.format.*; +import com.silverwrist.venice.servlets.format.menus.LeftMenu; public class Variables { @@ -35,19 +36,21 @@ public class Variables protected static final String ENGINE_ATTRIBUTE = "com.silverwrist.venice.core.Engine"; protected static final String COUNTRYLIST_ATTRIBUTE = "com.silverwrist.venice.db.CountryList"; protected static final String LANGUAGELIST_ATTRIBUTE = "com.silverwrist.venice.db.LanguageList"; - protected static final String TOPMENU_ATTRIBUTE = "com.silverwrist.venice.servlets.MenuTop"; // HttpSession ("session") attributes protected static final String USERCTXT_ATTRIBUTE = "user.context"; protected static final String MENU_ATTRIBUTE = "current.menu"; + // ServletRequest ("request" attributes) + protected static final String COOKIEJAR_ATTRIBUTE = "com.silverwrist.venice.servlets.CookieJar"; + // Servlet initialization parameters protected static final String ENGINE_INIT_PARAM = "venice.config"; // Cookie name - public static final String LOGIN_COOKIE = "VeniceLogin"; + public static final String LOGIN_COOKIE = "VeniceAuth"; - private static Category logger = Category.getInstance(Variables.class.getName()); + private static Category logger = Category.getInstance(Variables.class); private static Integer engine_gate = new Integer(0); /*-------------------------------------------------------------------------------- @@ -90,7 +93,8 @@ public class Variables } // end getVeniceEngine - public static UserContext getUserContext(ServletContext ctxt, ServletRequest request, HttpSession session) + public static UserContext getUserContext(ServletContext ctxt, HttpServletRequest request, + HttpSession session) throws ServletException { Object uctmp = session.getAttribute(USERCTXT_ATTRIBUTE); @@ -101,6 +105,33 @@ public class Variables { // use the Venice engine to create a new user context and save it off VeniceEngine engine = getVeniceEngine(ctxt); UserContext user = engine.createUserContext(request.getRemoteAddr()); + + // Did the user send a Venice authentication cookie? If so, try to use it. + Cookie[] cookies = request.getCookies(); + Cookie venice_cookie = null; + for (int i=0; (venice_cookie==null) && (i\n"); - rdat.writeFooter(out); } // end renderHere diff --git a/src/com/silverwrist/venice/servlets/format/BaseJSPData.java b/src/com/silverwrist/venice/servlets/format/BaseJSPData.java index 0dd516c..8889fe7 100644 --- a/src/com/silverwrist/venice/servlets/format/BaseJSPData.java +++ b/src/com/silverwrist/venice/servlets/format/BaseJSPData.java @@ -22,6 +22,8 @@ import java.io.IOException; import javax.servlet.*; import javax.servlet.http.*; import org.apache.log4j.*; +import com.silverwrist.venice.servlets.Variables; +import com.silverwrist.venice.servlets.format.menus.LeftMenu; public class BaseJSPData { @@ -114,6 +116,22 @@ public class BaseJSPData } // end transfer + public void renderMenu(HttpSession session, Writer out, RenderData rdat) throws IOException + { + ComponentRender menu = Variables.getMenu(session); + if (menu==null) + menu = (ComponentRender)(rdat.getLeftMenu("top")); + menu.renderHere(out,rdat); + + } // end renderMenu + + public void renderFixedMenu(Writer out, RenderData rdat) throws IOException + { + ComponentRender menu = (ComponentRender)(rdat.getLeftMenu("fixed")); + menu.renderHere(out,rdat); + + } // end renderFixedMenu + public void renderContent(ServletContext ctxt, Writer out, RenderData rdat) throws IOException, ServletException { @@ -142,7 +160,7 @@ public class BaseJSPData rdat.flushOutput(); // now make sure the included page is properly flushed return; - } // end if + } // end else if else // this is the fallback if we don't recognize the content new ErrorBox(null,"Internal Error: Content of invalid type",null).renderHere(out,rdat); diff --git a/src/com/silverwrist/venice/servlets/format/ConferenceActivity.java b/src/com/silverwrist/venice/servlets/format/ConferenceActivity.java index 9745dc5..5491c21 100644 --- a/src/com/silverwrist/venice/servlets/format/ConferenceActivity.java +++ b/src/com/silverwrist/venice/servlets/format/ConferenceActivity.java @@ -39,24 +39,39 @@ public class ConferenceActivity implements JSPRender private SIGContext sig; // the SIG we're in private ConferenceContext conf; // the conference being listed + private TopicContext topic; // the topic being listed private boolean posters; // is this a list of posters? private List records; // the actual data records + private String locator = null; // our locator /*-------------------------------------------------------------------------------- * Constructor *-------------------------------------------------------------------------------- */ - public ConferenceActivity(SIGContext sig, ConferenceContext conf, boolean posters) + public ConferenceActivity(SIGContext sig, ConferenceContext conf, TopicContext topic, boolean posters) throws DataException, AccessError { this.sig = sig; this.conf = conf; + this.topic = topic; this.posters = posters; - if (posters) - this.records = conf.getActivePosters(); + if (topic!=null) + { // do the report on the topic + if (posters) + this.records = topic.getActivePosters(); + else + this.records = topic.getActiveReaders(); + + } // end if else - this.records = conf.getActiveReaders(); + { // do the report on the conference + if (posters) + this.records = conf.getActivePosters(); + else + this.records = conf.getActiveReaders(); + + } // end else } // end constructor @@ -78,10 +93,22 @@ public class ConferenceActivity implements JSPRender public String getPageTitle(RenderData rdat) { - if (posters) - return "Users Posting in Conference " + conf.getName(); + if (topic!=null) + { // it's a topic report + if (posters) + return "Users Posting in Topic " + topic.getName(); + else + return "Users Reading Topic " + topic.getName(); + + } // end if else - return "Users Reading Conference " + conf.getName(); + { // it's a conference report + if (posters) + return "Users Posting in Conference " + conf.getName(); + else + return "Users Reading Conference " + conf.getName(); + + } // end else } // end getPageTitle @@ -113,12 +140,29 @@ public class ConferenceActivity implements JSPRender } // end getConfName + public String getTopicName() + { + if (topic==null) + return null; + else + return topic.getName(); + + } // end getTopicName + public String getLocator() { - return "sig=" + sig.getSIGID() + "&conf=" + conf.getConfID(); + if (locator==null) + locator = "sig=" + sig.getSIGID() + "&conf=" + conf.getConfID(); + return locator; } // end getLocator + public boolean isTopicReport() + { + return (topic!=null); + + } // end isTopicReport + public boolean isPosterReport() { return posters; diff --git a/src/com/silverwrist/venice/servlets/format/ConfirmBox.java b/src/com/silverwrist/venice/servlets/format/ConfirmBox.java index 07bf881..b8a2c24 100644 --- a/src/com/silverwrist/venice/servlets/format/ConfirmBox.java +++ b/src/com/silverwrist/venice/servlets/format/ConfirmBox.java @@ -122,7 +122,6 @@ public class ConfirmBox implements ContentRender out.write("\"No\"\n"); out.write("

\n"); - rdat.writeFooter(out); } // end renderHere diff --git a/src/com/silverwrist/venice/servlets/format/ContentDialog.java b/src/com/silverwrist/venice/servlets/format/ContentDialog.java index af5a878..81e30b8 100644 --- a/src/com/silverwrist/venice/servlets/format/ContentDialog.java +++ b/src/com/silverwrist/venice/servlets/format/ContentDialog.java @@ -216,7 +216,6 @@ public class ContentDialog implements Cloneable, ContentRender } // end if out.write("\n"); - rdat.writeFooter(out); } // end renderHere diff --git a/src/com/silverwrist/venice/servlets/format/ContentMenuPanel.java b/src/com/silverwrist/venice/servlets/format/ContentMenuPanel.java index 0eb44cd..f5172fd 100644 --- a/src/com/silverwrist/venice/servlets/format/ContentMenuPanel.java +++ b/src/com/silverwrist/venice/servlets/format/ContentMenuPanel.java @@ -135,7 +135,6 @@ public class ContentMenuPanel implements Cloneable, ContentRender } // end while out.write("\n"); - rdat.writeFooter(out); } // end renderHere diff --git a/src/com/silverwrist/venice/servlets/format/ErrorBox.java b/src/com/silverwrist/venice/servlets/format/ErrorBox.java index 6d32252..96d8321 100644 --- a/src/com/silverwrist/venice/servlets/format/ErrorBox.java +++ b/src/com/silverwrist/venice/servlets/format/ErrorBox.java @@ -78,7 +78,6 @@ public class ErrorBox extends VeniceServletResult implements ContentRender else out.write("Go back.\n"); out.write("

\n"); - rdat.writeFooter(out); } // end renderHere diff --git a/src/com/silverwrist/venice/servlets/format/LoginDialog.java b/src/com/silverwrist/venice/servlets/format/LoginDialog.java index 68d3172..b908dd5 100644 --- a/src/com/silverwrist/venice/servlets/format/LoginDialog.java +++ b/src/com/silverwrist/venice/servlets/format/LoginDialog.java @@ -37,8 +37,8 @@ public class LoginDialog extends ContentDialog addFormField(new CDPasswordFormFieldCommand("pass","Password",null,false,32,128, new CDImageButton("remind","bn_reminder.gif","Reminder", 80,24))); - //addFormField(new CDCheckBoxFormField("saveme","Save my user name and password for automatic logins", - // null,"Y")); + addFormField(new CDCheckBoxFormField("saveme","Remember me for next time so I can log in automatically", + null,"Y")); addCommandButton(new CDImageButton("login","bn_log_in.gif","Log In",80,24)); addCommandButton(new CDImageButton("cancel","bn_cancel.gif","Cancel",80,24)); diff --git a/src/com/silverwrist/venice/servlets/format/ManageConference.java b/src/com/silverwrist/venice/servlets/format/ManageConference.java index 7ea12a3..5d757e7 100644 --- a/src/com/silverwrist/venice/servlets/format/ManageConference.java +++ b/src/com/silverwrist/venice/servlets/format/ManageConference.java @@ -39,6 +39,7 @@ public class ManageConference implements JSPRender private SIGContext sig; // the SIG we're in private ConferenceContext conf; // the conference being listed + private String locator = null; // the locator we use /*-------------------------------------------------------------------------------- * Constructor @@ -116,7 +117,9 @@ public class ManageConference implements JSPRender public String getLocator() { - return "sig=" + sig.getSIGID() + "&conf=" + conf.getConfID(); + if (locator==null) + locator = "sig=" + sig.getSIGID() + "&conf=" + conf.getConfID(); + return locator; } // end getLocator @@ -128,8 +131,7 @@ public class ManageConference implements JSPRender public boolean displayAdminSection() { - return conf.canChangeConference(); - // TODO: needs to have "delete" permission OR'ed in + return conf.canChangeConference() || conf.canDeleteConference(); } // end displayAdminSection diff --git a/src/com/silverwrist/venice/servlets/format/RenderConfig.java b/src/com/silverwrist/venice/servlets/format/RenderConfig.java index 1f45dbe..b634a3a 100644 --- a/src/com/silverwrist/venice/servlets/format/RenderConfig.java +++ b/src/com/silverwrist/venice/servlets/format/RenderConfig.java @@ -31,6 +31,7 @@ import com.silverwrist.util.StringUtil; import com.silverwrist.venice.core.ConfigException; import com.silverwrist.venice.core.UserContext; import com.silverwrist.venice.servlets.Variables; +import com.silverwrist.venice.servlets.format.menus.LeftMenu; public class RenderConfig { @@ -57,7 +58,8 @@ public class RenderConfig private String image_url; private String static_url; private String site_logo; - private Hashtable stock_messages; + private HashMap stock_messages; + private HashMap menus; /*-------------------------------------------------------------------------------- * Constructor @@ -171,9 +173,10 @@ public class RenderConfig } // end if // Initialize the stock messages list. - stock_messages = new Hashtable(); + stock_messages = new HashMap(); NodeList msg_nodes = msg_sect.getChildNodes(); - for (int i=0; i section - bail out now! + logger.fatal("config document has no section"); + throw new ConfigException("no section found in config file",root); + + } // end if + + // Initialize the menus list. + menus = new HashMap(); + NodeList menu_nodes = menu_sect.getChildNodes(); + for (i=0; i subnodes and use them to initialize menus + Node mn = menu_nodes.item(i); + if (mn.getNodeType()==Node.ELEMENT_NODE) + { // found an element - now check it's name + if (mn.getNodeName().equals("menudef")) + { // root of a menu definition - get its ID, build it, and save it + Element mel = (Element)mn; + String menuid = mel.getAttribute("id"); + if (menuid==null) + { // no menu ID attribute + logger.fatal(" seen with no \"id\" attribute"); + throw new ConfigException(" seen with no \"id\" attribute",mel); + + } // end if + + // create the menu and add it to the mapping + LeftMenu menu = new LeftMenu(mel,menuid); + menus.put(menuid,menu); + if (logger.isDebugEnabled()) + logger.debug("menu \"" + menuid + "\" defined"); + + } // end if (found the root of a menu definition) + else + { // unknown element - bail out! + logger.fatal("config document has unknown node <" + mn.getNodeName() + + "/> inside "); + throw new ConfigException("unknown node name <" + mn.getNodeName() + "/> in ", + menu_sect); + + } // end else + + } // end if + + } // end for + + if (logger.isDebugEnabled()) + logger.debug(menus.size() + " menu definitions loaded from config"); + } // end constructor /*-------------------------------------------------------------------------------- @@ -337,20 +390,6 @@ public class RenderConfig } // end getRequiredBullet - void writeFooter(Writer out) throws IOException - { - out.write("


\n" - + "\n\n\n" - + "
\n"); - out.write(getStdFontTag(null,1)); - out.write(getStockMessage("footer-text")); - out.write("\n\n" - + "\"Powered\n
\n"); - - } // end writeFooter - void writeContentHeader(Writer out, String primary, String secondary) throws IOException { out.write(getStdFontTag("#3333AA",5) + "" + StringUtil.encodeHTML(primary) + ""); @@ -374,6 +413,12 @@ public class RenderConfig } // end writeStockMessage + public LeftMenu getLeftMenu(String identifier) + { + return (LeftMenu)(menus.get(identifier)); + + } // end getLeftMenu + /*-------------------------------------------------------------------------------- * Static operations for use by VeniceServlet *-------------------------------------------------------------------------------- @@ -410,14 +455,14 @@ public class RenderConfig HttpServletResponse response) throws ServletException { UserContext uc = Variables.getUserContext(ctxt,request,request.getSession(true)); - return new RenderData(getRenderConfig(ctxt),uc,request,response); + return new RenderData(getRenderConfig(ctxt),uc,ctxt,request,response); } // end createRenderData public static RenderData createRenderData(ServletContext ctxt, UserContext uc, HttpServletRequest request, HttpServletResponse response) throws ServletException { - return new RenderData(getRenderConfig(ctxt),uc,request,response); + return new RenderData(getRenderConfig(ctxt),uc,ctxt,request,response); } // end createRenderData diff --git a/src/com/silverwrist/venice/servlets/format/RenderData.java b/src/com/silverwrist/venice/servlets/format/RenderData.java index 044ec9d..351c114 100644 --- a/src/com/silverwrist/venice/servlets/format/RenderData.java +++ b/src/com/silverwrist/venice/servlets/format/RenderData.java @@ -29,6 +29,7 @@ import com.silverwrist.venice.core.IDUtils; import com.silverwrist.venice.core.UserContext; import com.silverwrist.venice.db.PostLinkRewriter; import com.silverwrist.venice.db.UserNameRewriter; +import com.silverwrist.venice.servlets.format.menus.LeftMenu; public class RenderData { @@ -47,6 +48,7 @@ public class RenderData */ private RenderConfig rconf; + private ServletContext ctxt; private HttpServletRequest request; private HttpServletResponse response; private boolean can_gzip = false; @@ -60,9 +62,11 @@ public class RenderData *-------------------------------------------------------------------------------- */ - RenderData(RenderConfig rconf, UserContext uc, HttpServletRequest request, HttpServletResponse response) + RenderData(RenderConfig rconf, UserContext uc, ServletContext ctxt, HttpServletRequest request, + HttpServletResponse response) { this.rconf = rconf; + this.ctxt = ctxt; this.request = request; this.response = response; @@ -167,7 +171,13 @@ public class RenderData { return "/format/" + name; - } // end getFullFormatJSPPath + } // end getFormatJSPPath + + public String getStaticIncludePath(String name) + { + return "/static/" + name; + + } // end getStaticIncludePath public String getStdFontTag(String color, int size) { @@ -193,12 +203,6 @@ public class RenderData } // end getRequiredBullet - public void writeFooter(Writer out) throws IOException - { - rconf.writeFooter(out); - - } // end writeFooter - public void writeContentHeader(Writer out, String primary, String secondary) throws IOException { rconf.writeContentHeader(out,primary,secondary); @@ -250,6 +254,12 @@ public class RenderData } // end writeStockMessage + public LeftMenu getLeftMenu(String identifier) + { + return rconf.getLeftMenu(identifier); + + } // end getLeftMenu + public String formatDateForDisplay(Date date) { if (display_date==null) @@ -491,4 +501,19 @@ public class RenderData } // end rewritePostData + public String mapToPath(String path) + { + return ctxt.getRealPath(path); + + } // end mapToPath + + public Cookie createCookie(String name, String value, int age) + { + Cookie rc = new Cookie(name,value); + rc.setMaxAge(age); + rc.setPath(request.getContextPath()); + return rc; + + } // end createCookie + } // end class RenderData diff --git a/src/com/silverwrist/venice/servlets/format/ReportConferenceMenu.java b/src/com/silverwrist/venice/servlets/format/ReportConferenceMenu.java new file mode 100644 index 0000000..eb21b55 --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/ReportConferenceMenu.java @@ -0,0 +1,128 @@ +/* + * 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.venice.servlets.format; + +import java.util.*; +import javax.servlet.*; +import javax.servlet.http.*; +import com.silverwrist.venice.core.*; + +public class ReportConferenceMenu implements JSPRender +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + // Attribute name for request attribute + protected static final String ATTR_NAME = "com.silverwrist.venice.content.ReportConferenceMenu"; + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private SIGContext sig; // the SIG we're in + private ConferenceContext conf; // the conference being listed + private List topics; // the topics in this conference + private String locator = null; // the locator + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public ReportConferenceMenu(SIGContext sig, ConferenceContext conf) throws DataException, AccessError + { + this.sig = sig; + this.conf = conf; + this.topics = conf.getTopicList(ConferenceContext.GET_ALL,ConferenceContext.SORT_NUMBER); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * External static functions + *-------------------------------------------------------------------------------- + */ + + public static ReportConferenceMenu retrieve(ServletRequest request) + { + return (ReportConferenceMenu)(request.getAttribute(ATTR_NAME)); + + } // end retrieve + + /*-------------------------------------------------------------------------------- + * Implementations from interface VeniceContent + *-------------------------------------------------------------------------------- + */ + + public String getPageTitle(RenderData rdat) + { + return "Conference Reports: " + conf.getName(); + + } // end getPageTitle + + /*-------------------------------------------------------------------------------- + * Implementations from interface JSPRender + *-------------------------------------------------------------------------------- + */ + + public void store(ServletRequest request) + { + request.setAttribute(ATTR_NAME,this); + + } // end store + + public String getTargetJSPName() + { + return "report_conf.jsp"; + + } // end getTargetJSPName + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + public int getConfID() + { + return conf.getConfID(); + + } // end getConfID + + public String getConfName() + { + return conf.getName(); + + } // end getConfName + + public String getLocator() + { + if (locator==null) + locator = "sig=" + sig.getSIGID() + "&conf=" + conf.getConfID(); + return locator; + + } // end getLocator + + public Iterator getTopics() + { + return topics.iterator(); + + } // end getTopics + +} // end class ReportConferenceMenu diff --git a/src/com/silverwrist/venice/servlets/format/StaticRender.java b/src/com/silverwrist/venice/servlets/format/StaticRender.java new file mode 100644 index 0000000..f929232 --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/StaticRender.java @@ -0,0 +1,184 @@ +/* + * 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.venice.servlets.format; + +import java.io.*; +import com.silverwrist.util.cachemap.CacheMap; + +public class StaticRender implements ContentRender +{ + /*-------------------------------------------------------------------------------- + * Static data values + *-------------------------------------------------------------------------------- + */ + + private static CacheMap cache = new CacheMap(15,25); + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String name; + private boolean processed = false; + private String title = null; + private String content = null; + + /*-------------------------------------------------------------------------------- + * Static data values + *-------------------------------------------------------------------------------- + */ + + protected StaticRender(String name) + { + this.name = name; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Internal functions + *-------------------------------------------------------------------------------- + */ + + private static String searchBetweenTags(StringBuffer data, String search, String tagname) + { + tagname = tagname.toUpperCase(); + String start = "<" + tagname; + String end = ""; + + int startpos = search.indexOf(start); + if (startpos<0) + return null; + startpos += start.length(); + + int bkt_pos = search.indexOf('>',startpos); + if (bkt_pos<0) + return null; + + int end_pos = search.indexOf(end,++bkt_pos); + if (end_pos<0) + return data.substring(bkt_pos); + else + return data.substring(bkt_pos,end_pos); + + } // end searchBetweenTags + + private synchronized void process(RenderData rdat) + { + if (processed) + return; // check and set flag + + // Map the content path to a real filename. + String real_path = rdat.mapToPath(rdat.getStaticIncludePath(name)); + if (real_path==null) + { // not found! + title = name; + content = "File not mappable: " + name; + return; + + } // end if + + // Read in the whole thing. + StringBuffer raw_file = new StringBuffer(); + try + { // read in from the file + FileReader rdr = new FileReader(real_path); + char[] buffer = new char[4096]; + int rd = rdr.read(buffer); + while (rd>=0) + { // read in the raw characters + if (rd>0) + raw_file.append(buffer,0,rd); + rd = rdr.read(buffer); + + } // end while + + rdr.close(); + + } // end try + catch (IOException ioe) + { // I/O exception - just discard + title = name; + content = "I/O error reading " + name + ": " + ioe.getMessage(); + return; + + } // end catch + + // make the upper-case search page and use that to locate the page title and body + String search_page = raw_file.toString().toUpperCase(); + title = searchBetweenTags(raw_file,search_page,"TITLE"); + content = searchBetweenTags(raw_file,search_page,"BODY"); + if (content==null) + { // no content? + content = "No content seen on " + name; + processed = false; + + } // end if + + processed = true; // set the flag to indicate we've got everything + + } // end process + + /*-------------------------------------------------------------------------------- + * Implementations from interface VeniceContent + *-------------------------------------------------------------------------------- + */ + + public String getPageTitle(RenderData rdat) + { + process(rdat); + if (title==null) + return name; + else + return title; + + } // end getPageTitle + + /*-------------------------------------------------------------------------------- + * Implementations from interface ContentRender + *-------------------------------------------------------------------------------- + */ + + public void renderHere(Writer out, RenderData rdat) throws IOException + { + process(rdat); + if (content!=null) + out.write(content); + + } // end renderHere + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + public static StaticRender getStaticRender(String name) + { + StaticRender rc = (StaticRender)(cache.get(name)); + if (rc==null) + { // create a new object and cache it + rc = new StaticRender(name); + cache.put(name,rc); + + } // end if + + return rc; + + } // end getStaticRender + +} // end class StaticRender diff --git a/src/com/silverwrist/venice/servlets/format/TextMessageDialog.java b/src/com/silverwrist/venice/servlets/format/TextMessageDialog.java index 89d8314..82118fd 100644 --- a/src/com/silverwrist/venice/servlets/format/TextMessageDialog.java +++ b/src/com/silverwrist/venice/servlets/format/TextMessageDialog.java @@ -149,7 +149,6 @@ public class TextMessageDialog implements ContentRender } // end for out.write("\n"); - rdat.writeFooter(out); } // end renderHere diff --git a/src/com/silverwrist/venice/servlets/format/TopDisplay.java b/src/com/silverwrist/venice/servlets/format/TopDisplay.java index 35e63ab..aa1b72a 100644 --- a/src/com/silverwrist/venice/servlets/format/TopDisplay.java +++ b/src/com/silverwrist/venice/servlets/format/TopDisplay.java @@ -243,7 +243,6 @@ public class TopDisplay implements ContentRender // Finish up. out.write("\n"); - rdat.writeFooter(out); } // end renderHere diff --git a/src/com/silverwrist/util/collections/ReadOnlyVector.java b/src/com/silverwrist/venice/servlets/format/menus/AbsoluteLeftMenuItem.java similarity index 64% rename from src/com/silverwrist/util/collections/ReadOnlyVector.java rename to src/com/silverwrist/venice/servlets/format/menus/AbsoluteLeftMenuItem.java index 07022c1..22e0572 100644 --- a/src/com/silverwrist/util/collections/ReadOnlyVector.java +++ b/src/com/silverwrist/venice/servlets/format/menus/AbsoluteLeftMenuItem.java @@ -15,58 +15,43 @@ * * Contributor(s): */ -package com.silverwrist.util.collections; +package com.silverwrist.venice.servlets.format.menus; -import java.util.*; +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.venice.servlets.format.RenderData; -public class ReadOnlyVector extends AbstractList +class AbsoluteLeftMenuItem extends LeftMenuItem { /*-------------------------------------------------------------------------------- * Attributes *-------------------------------------------------------------------------------- */ - private Vector my_vec; // local vector + String url; /*-------------------------------------------------------------------------------- * Constructor *-------------------------------------------------------------------------------- */ - public ReadOnlyVector(Vector vec) + AbsoluteLeftMenuItem(Element elt) { - my_vec = vec; - my_vec.trimToSize(); + super(elt); + DOMElementHelper h = new DOMElementHelper(elt); + url = h.getSubElementText("absolute"); } // end constructor /*-------------------------------------------------------------------------------- - * finalize() method + * Overrides from class LeftMenuItem *-------------------------------------------------------------------------------- */ - protected void finalize() throws Throwable + protected void appendURL(StringBuffer sbuf, RenderData rdat) { - my_vec = null; - super.finalize(); + sbuf.append(url); - } // end finalize + } // end appendURL - /*-------------------------------------------------------------------------------- - * 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 +} // end class AbsoluteLeftMenuItem diff --git a/src/com/silverwrist/venice/servlets/format/menus/FrameLeftMenuItem.java b/src/com/silverwrist/venice/servlets/format/menus/FrameLeftMenuItem.java new file mode 100644 index 0000000..ec0fd32 --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/menus/FrameLeftMenuItem.java @@ -0,0 +1,57 @@ +/* + * 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.venice.servlets.format.menus; + +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.venice.servlets.format.RenderData; + +class FrameLeftMenuItem extends LeftMenuItem +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + String url; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + FrameLeftMenuItem(Element elt) + { + super(elt); + DOMElementHelper h = new DOMElementHelper(elt); + url = h.getSubElementText("frame"); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class LeftMenuItem + *-------------------------------------------------------------------------------- + */ + + protected void appendURL(StringBuffer sbuf, RenderData rdat) + { + sbuf.append(rdat.getEncodedServletPath("frame/" + url)); + + } // end appendURL + +} // end class FrameLeftMenuItem diff --git a/src/com/silverwrist/venice/servlets/format/menus/LeftMenu.java b/src/com/silverwrist/venice/servlets/format/menus/LeftMenu.java new file mode 100644 index 0000000..1748894 --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/menus/LeftMenu.java @@ -0,0 +1,188 @@ +/* + * 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.venice.servlets.format.menus; + +import java.io.Writer; +import java.io.IOException; +import java.util.*; +import org.apache.log4j.*; +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.venice.core.ConfigException; +import com.silverwrist.venice.servlets.format.ComponentRender; +import com.silverwrist.venice.servlets.format.RenderData; + +public class LeftMenu implements ComponentRender +{ + /*-------------------------------------------------------------------------------- + * Internal class representing a header component + *-------------------------------------------------------------------------------- + */ + + static class Header implements ComponentRender + { + private String txt; // the actual stored text + + Header(Element elt) + { + DOMElementHelper h = new DOMElementHelper(elt); + StringBuffer buf = new StringBuffer(""); + buf.append(StringUtil.encodeHTML(h.getElementText())).append("
\n"); + txt = buf.toString(); + + } // end constructor + + public void renderHere(Writer out, RenderData rdat) throws IOException + { + out.write(txt); + + } // end renderHere + + } // end class Header + + /*-------------------------------------------------------------------------------- + * Internal class representing a separator component + *-------------------------------------------------------------------------------- + */ + + static class Separator implements ComponentRender + { + Separator() + { // do nothing + } // end constructor + + public void renderHere(Writer out, RenderData rdat) throws IOException + { + out.write("
\n"); + + } // end renderHere + + } // end class Separator + + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Category logger = Category.getInstance(LeftMenu.class); + private static final Separator separator_singleton = new Separator(); + + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String identifier; + private ArrayList menu_items = new ArrayList(); + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public LeftMenu(Element elt, String identifier) throws ConfigException + { + if (!(elt.getNodeName().equals("menudef"))) + { // just some shorts-checking here to make sure the element is OK + logger.fatal("huh?!? this should have been a if it got here!"); + throw new ConfigException("not a element"); + + } // end if + + NodeList items = elt.getChildNodes(); + for (int i=0; i element has no subelement"); + throw new ConfigException(" element has no subelement",h.getElement()); + + } // end if + + LeftMenuItem mitem = null; + if (h.hasChildElement("servlet")) + mitem = new ServletLeftMenuItem(h.getElement()); + else if (h.hasChildElement("absolute")) + mitem = new AbsoluteLeftMenuItem(h.getElement()); + else if (h.hasChildElement("frame")) + mitem = new FrameLeftMenuItem(h.getElement()); + else + { // we don't know what type of menu this is! + logger.fatal("unknown type seen in menu"); + throw new ConfigException("unknown type seen in menu",h.getElement()); + + } // end else + + menu_items.add(mitem); + + } // end if + else if (n.getNodeName().equals("header")) + menu_items.add(new Header((Element)n)); // add a new header + else if (n.getNodeName().equals("separator")) + menu_items.add(separator_singleton); // all separators are exactly the same + else + { // menu definition has an unknown item + logger.fatal("unknown element <" + n.getNodeName() + "/> inside "); + throw new ConfigException("unknown element <" + n.getNodeName() + "/> inside ",n); + + } // end else + + } // end if (an element node) + + } // end for (each child node) + + this.identifier = identifier; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentRender + *-------------------------------------------------------------------------------- + */ + + public void renderHere(Writer out, RenderData rdat) throws IOException + { + Iterator it = menu_items.iterator(); + while (it.hasNext()) + { // render each menu item in turn + ComponentRender cr = (ComponentRender)(it.next()); + cr.renderHere(out,rdat); + + } // end while + + } // end renderHere + + /*-------------------------------------------------------------------------------- + * External operations + *-------------------------------------------------------------------------------- + */ + + public String getIdentifier() + { + return identifier; + + } // end getIdentifier + +} // end class LeftMenu + diff --git a/src/com/silverwrist/venice/servlets/format/menus/LeftMenuItem.java b/src/com/silverwrist/venice/servlets/format/menus/LeftMenuItem.java new file mode 100644 index 0000000..f3da3ab --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/menus/LeftMenuItem.java @@ -0,0 +1,93 @@ +/* + * 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.venice.servlets.format.menus; + +import java.io.Writer; +import java.io.IOException; +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.venice.servlets.format.ComponentRender; +import com.silverwrist.venice.servlets.format.RenderData; + +abstract class LeftMenuItem implements ComponentRender +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + private String text; + private boolean disabled = false; + private boolean new_window = false; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + protected LeftMenuItem(Element elt) + { + DOMElementHelper h = new DOMElementHelper(elt); + text = StringUtil.encodeHTML(h.getSubElementText("text")); + if (h.hasChildElement("disabled")) + disabled = true; + if (h.hasChildElement("new-window")) + new_window = true; + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Abstract functions which MUST be overridden + *-------------------------------------------------------------------------------- + */ + + protected abstract void appendURL(StringBuffer sbuf, RenderData rdat); + + /*-------------------------------------------------------------------------------- + * Implementations from interface ComponentRender + *-------------------------------------------------------------------------------- + */ + + public void renderHere(Writer out, RenderData rdat) throws IOException + { + StringBuffer buf = new StringBuffer(); + + if (disabled) + buf.append(""); + else + { // write the tag + buf.append("'); + + } // end else (writing tag) + + buf.append(text); + if (disabled) + buf.append(""); + else + buf.append(""); + buf.append("
\n"); + out.write(buf.toString()); + + } // end renderHere + +} // end class LeftMenuItem diff --git a/src/com/silverwrist/venice/servlets/format/menus/ServletLeftMenuItem.java b/src/com/silverwrist/venice/servlets/format/menus/ServletLeftMenuItem.java new file mode 100644 index 0000000..8785b9d --- /dev/null +++ b/src/com/silverwrist/venice/servlets/format/menus/ServletLeftMenuItem.java @@ -0,0 +1,57 @@ +/* + * 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.venice.servlets.format.menus; + +import org.w3c.dom.*; +import com.silverwrist.util.*; +import com.silverwrist.venice.servlets.format.RenderData; + +class ServletLeftMenuItem extends LeftMenuItem +{ + /*-------------------------------------------------------------------------------- + * Attributes + *-------------------------------------------------------------------------------- + */ + + String url; + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + ServletLeftMenuItem(Element elt) + { + super(elt); + DOMElementHelper h = new DOMElementHelper(elt); + url = h.getSubElementText("servlet"); + + } // end constructor + + /*-------------------------------------------------------------------------------- + * Overrides from class LeftMenuItem + *-------------------------------------------------------------------------------- + */ + + protected void appendURL(StringBuffer sbuf, RenderData rdat) + { + sbuf.append(rdat.getEncodedServletPath(url)); + + } // end appendURL + +} // end class ServletLeftMenuItem diff --git a/web/format/attach_form.jsp b/web/format/attach_form.jsp index c79b568..d7b4f83 100644 --- a/web/format/attach_form.jsp +++ b/web/format/attach_form.jsp @@ -38,4 +38,3 @@ WIDTH=80 HEIGHT=24 BORDER=0>

-<% rdat.writeFooter(out); %> diff --git a/web/format/base.jsp b/web/format/base.jsp index f0b7e66..5b76682 100644 --- a/web/format/base.jsp +++ b/web/format/base.jsp @@ -20,19 +20,6 @@ <%@ page import = "com.silverwrist.venice.core.*" %> <%@ page import = "com.silverwrist.venice.servlets.Variables" %> <%@ page import = "com.silverwrist.venice.servlets.format.*" %> -<%! - -private static void renderMenu(HttpSession session, java.io.Writer out, RenderData rdat) - throws java.io.IOException -{ - ComponentRender menu = Variables.getMenu(session); - if (menu==null) - menu = new MenuTop(); - menu.renderHere(out,rdat); - -} // end renderMenu - -%> <% BaseJSPData basedat = BaseJSPData.retrieve(request); Variables.failIfNull(basedat); @@ -97,36 +84,51 @@ private static void renderMenu(HttpSession session, java.io.Writer out, RenderDa <% if (rdat.useHTMLComments()) { %><% } %> - - - -
- - <% if (rdat.useHTMLComments()) { %><% } %> - +
<%= rdat.getStdFontTag(null,2) %> - <% if (rdat.useHTMLComments()) { %><% } %> - <% renderMenu(session,out,rdat); %> -
+ + +
+ + <% if (rdat.useHTMLComments()) { %><% } %> + - - + + - <% if (rdat.useHTMLComments()) { %><% } %> + <% if (rdat.useHTMLComments()) { %><% } %> -
<%= rdat.getStdFontTag(null,2) %> + <% if (rdat.useHTMLComments()) { %><% } %> + <% basedat.renderMenu(session,out,rdat); %> +
 
<%= rdat.getStdFontTag(null,2) %> - <% if (rdat.useHTMLComments()) { %><% } %> - About This Site
- Documentation
- About Venice -
 
<%= rdat.getStdFontTag(null,2) %> + <% if (rdat.useHTMLComments()) { %><% } %> + <% basedat.renderFixedMenu(out,rdat); %> +
-
+
-
+ <% if (rdat.useHTMLComments()) { %><% } %> <% basedat.renderContent(application,out,rdat); %> - <% if (rdat.useHTMLComments()) { %><% } %> -
-
+ <% if (rdat.useHTMLComments()) { %><% } %> + + + +   + + <% if (rdat.useHTMLComments()) { %><% } %> +


+ + + +
<%= rdat.getStdFontTag(null,1) %> + <%= rdat.getStockMessage("footer-text") %> + + " ALT="Powered by Venice" + WIDTH=140 HEIGHT=80 BORDER=0 HSPACE=0 VSPACE=0> +
+ + + diff --git a/web/format/conf_activity.jsp b/web/format/conf_activity.jsp index 65b3156..a1bcba8 100644 --- a/web/format/conf_activity.jsp +++ b/web/format/conf_activity.jsp @@ -25,11 +25,18 @@ Variables.failIfNull(data); RenderData rdat = RenderConfig.createRenderData(application,request,response); %> -<% rdat.writeContentHeader(out,(data.isPosterReport() ? "Posters in Conference:" - : "Readers in Conference:"),data.getConfName()); %> +<% + if (data.isTopicReport()) + rdat.writeContentHeader(out,(data.isPosterReport() ? "Posters in Topic:" + : "Readers in Topic:"), + data.getTopicName() + " in " + data.getConfName()); + else + rdat.writeContentHeader(out,(data.isPosterReport() ? "Posters in Conference:" + : "Readers in Conference:"),data.getConfName()); +%> <%= rdat.getStdFontTag(null,2) %> - ">Return to - Manage Conference Menu + ">Return to + Conference Reports Menu

<% if (data.anyElements()) { %> @@ -79,11 +86,18 @@ <% } else { %> <%= rdat.getStdFontTag(null,2) %> - <% if (data.isPosterReport()) { %> - No posters to conference "<%= StringUtil.encodeHTML(data.getConfName()) %>" found. + <% if (data.isTopicReport()) { %> + <% if (data.isPosterReport()) { %> + No posters to topic "<%= data.getTopicName() %>" found. + <% } else { %> + No readers of topic "<%= data.getTopicName() %>" found. + <% } // end if %> <% } else { %> - No readers of conference "<%= StringUtil.encodeHTML(data.getConfName()) %>" found. + <% if (data.isPosterReport()) { %> + No posters to conference "<%= StringUtil.encodeHTML(data.getConfName()) %>" found. + <% } else { %> + No readers of conference "<%= StringUtil.encodeHTML(data.getConfName()) %>" found. + <% } // end if %> <% } // end if %> <% } // end if %> -

<% rdat.writeFooter(out); %> diff --git a/web/format/conf_member.jsp b/web/format/conf_member.jsp index ccc9814..b3b717e 100644 --- a/web/format/conf_member.jsp +++ b/web/format/conf_member.jsp @@ -151,4 +151,3 @@ WIDTH=80 HEIGHT=24 BORDER=0>
<% } // end if %> -<% rdat.writeFooter(out); %> diff --git a/web/format/conf_sequence.jsp b/web/format/conf_sequence.jsp index db9903b..14932af 100644 --- a/web/format/conf_sequence.jsp +++ b/web/format/conf_sequence.jsp @@ -137,4 +137,3 @@ <% } else { %> <%= rdat.getStdFontTag(null,2) %>There are no conferences in this SIG. <% } // end if %> -<% rdat.writeFooter(out); %> diff --git a/web/format/conferences.jsp b/web/format/conferences.jsp index e39bad0..6595de9 100644 --- a/web/format/conferences.jsp +++ b/web/format/conferences.jsp @@ -72,4 +72,3 @@ BORDER=0>  <% } // end if %> -<% rdat.writeFooter(out); %> diff --git a/web/format/find.jsp b/web/format/find.jsp index e08f384..d03a243 100644 --- a/web/format/find.jsp +++ b/web/format/find.jsp @@ -286,4 +286,3 @@ private static String getActivityString(SIGContext sig, RenderData rdat)
<% } // end if (results found) %> -<% rdat.writeFooter(out); %> diff --git a/web/format/hotlist.jsp b/web/format/hotlist.jsp index 2dfcbb0..c2ab595 100644 --- a/web/format/hotlist.jsp +++ b/web/format/hotlist.jsp @@ -96,4 +96,3 @@ by visiting the conferences and pressing the "Add to Hotlist" button. <% } // end if %> -<% rdat.writeFooter(out); %> diff --git a/web/format/invitation.jsp b/web/format/invitation.jsp index 97eeb2c..b59ed05 100644 --- a/web/format/invitation.jsp +++ b/web/format/invitation.jsp @@ -49,4 +49,3 @@ -<% rdat.writeFooter(out); %> \ No newline at end of file diff --git a/web/format/manage_aliases.jsp b/web/format/manage_aliases.jsp index 411574c..9a19efb 100644 --- a/web/format/manage_aliases.jsp +++ b/web/format/manage_aliases.jsp @@ -68,4 +68,3 @@ -<% rdat.writeFooter(out); %> diff --git a/web/format/manage_conf.jsp b/web/format/manage_conf.jsp index 3fccf1e..2fa089a 100644 --- a/web/format/manage_conf.jsp +++ b/web/format/manage_conf.jsp @@ -61,13 +61,9 @@ Conference Aliases

">Manage Conference Members

- ">Conference - Posters Report

- ">Conference - Readers/Lurkers Report

+ ">Conference + Activity Reports

">Delete Conference

<% } // end if (displaying admin section) %> - -<% rdat.writeFooter(out); %> diff --git a/web/format/newsigwelcome.jsp b/web/format/newsigwelcome.jsp index 8d6ce15..3e0acc7 100644 --- a/web/format/newsigwelcome.jsp +++ b/web/format/newsigwelcome.jsp @@ -40,5 +40,3 @@ Invite Users -<% rdat.writeFooter(out); %> - diff --git a/web/format/newtopic.jsp b/web/format/newtopic.jsp index d7a5f53..9c4d236 100644 --- a/web/format/newtopic.jsp +++ b/web/format/newtopic.jsp @@ -48,7 +48,7 @@
<%= rdat.getStdFontTag(null,2) %>New topic name:
- +
<%= rdat.getStdFontTag(null,2) %>Your name/header:
@@ -77,4 +77,3 @@
-<% rdat.writeFooter(out); %> diff --git a/web/format/posts.jsp b/web/format/posts.jsp index 3b83993..ffbd496 100644 --- a/web/format/posts.jsp +++ b/web/format/posts.jsp @@ -176,7 +176,7 @@ ) <% if (msg.hasAttachment()) { %> " TARGET="_blank">" ALT="(Attachment <%= msg.getAttachmentFilename() %> - <%= msg.getAttachmentLength() %> bytes)" WIDTH=16 HEIGHT=16 BORDER=0> @@ -341,4 +341,3 @@ <% } else if (data.isTopicFrozen()) { %>

<%= rdat.getStdFontTag(null,2) %>This is a Frozen Topic
<% } // end if %> -<% rdat.writeFooter(out); %> diff --git a/web/format/preview.jsp b/web/format/preview.jsp index 3fd11a4..ca5599f 100644 --- a/web/format/preview.jsp +++ b/web/format/preview.jsp @@ -84,4 +84,3 @@ -<% rdat.writeFooter(out); %> diff --git a/web/format/report_conf.jsp b/web/format/report_conf.jsp new file mode 100644 index 0000000..70ddddd --- /dev/null +++ b/web/format/report_conf.jsp @@ -0,0 +1,73 @@ +<%-- + 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): +--%> +<%@ page import = "java.util.*" %> +<%@ page import = "com.silverwrist.util.StringUtil" %> +<%@ page import = "com.silverwrist.venice.core.*" %> +<%@ page import = "com.silverwrist.venice.servlets.Variables" %> +<%@ page import = "com.silverwrist.venice.servlets.format.*" %> +<% + ReportConferenceMenu data = ReportConferenceMenu.retrieve(request); + Variables.failIfNull(data); + RenderData rdat = RenderConfig.createRenderData(application,request,response); + String stdfont = rdat.getStdFontTag(null,2); + String partial; +%> +<% if (rdat.useHTMLComments()) { %><% } %> +<% rdat.writeContentHeader(out,"Conference Reports:",data.getConfName()); %> + +<%= stdfont %> + ">Return to Manage + Conference Menu +

+ + + + + + + + + + + <% partial = "confops?" + data.getLocator() + "&cmd="; %> + + + + + <% Iterator it = data.getTopics(); %> + <% while (it.hasNext()) { %> + <% + TopicContext topic = (TopicContext)(it.next()); + partial = "confops?" + data.getLocator() + "&top=" + topic.getTopicNumber() + "&cmd="; + %> + + + + + + + <% } // end while %> +
<%= stdfont %>#<%= stdfont %>Topic Name<%= stdfont %>Reports
 <%= stdfont %>(Entire conference)<%= stdfont %> + ">Posters + <%= stdfont %> + ">Readers/Lurkers +
<%= stdfont %><%= topic.getTopicNumber() %><%= stdfont %><%= topic.getName() %><%= stdfont %> + ">Posters + <%= stdfont %> + ">Readers/Lurkers +

diff --git a/web/format/sig_member.jsp b/web/format/sig_member.jsp index 9618d9f..9f6015b 100644 --- a/web/format/sig_member.jsp +++ b/web/format/sig_member.jsp @@ -148,4 +148,3 @@ WIDTH=80 HEIGHT=24 BORDER=0>
<% } // end if %> -<% rdat.writeFooter(out); %> diff --git a/web/format/sigcatbrowser.jsp b/web/format/sigcatbrowser.jsp index cbc8c48..4a919d5 100644 --- a/web/format/sigcatbrowser.jsp +++ b/web/format/sigcatbrowser.jsp @@ -69,4 +69,3 @@ SIG Administration menu.

-<% rdat.writeFooter(out); %> diff --git a/web/format/siglist.jsp b/web/format/siglist.jsp index 89cb8b7..3cd6e4d 100644 --- a/web/format/siglist.jsp +++ b/web/format/siglist.jsp @@ -62,4 +62,3 @@ <% } else { %> <%= rdat.getStdFontTag(null,2) %>You are not a member of any SIGs. <% } // end if %> -<% rdat.writeFooter(out); %> diff --git a/web/format/sigprofile.jsp b/web/format/sigprofile.jsp index 9691f96..84f534f 100644 --- a/web/format/sigprofile.jsp +++ b/web/format/sigprofile.jsp @@ -100,4 +100,3 @@ -<% rdat.writeFooter(out); %> diff --git a/web/format/sigwelcome.jsp b/web/format/sigwelcome.jsp index fe8fd29..ebb7c84 100644 --- a/web/format/sigwelcome.jsp +++ b/web/format/sigwelcome.jsp @@ -33,4 +33,3 @@ has elected to provide. Enjoy your membership!

-<% rdat.writeFooter(out); %> diff --git a/web/format/slippage.jsp b/web/format/slippage.jsp index 286da09..c39fbd8 100644 --- a/web/format/slippage.jsp +++ b/web/format/slippage.jsp @@ -106,6 +106,3 @@ -<% rdat.writeFooter(out); %> - - diff --git a/web/format/top_content.jsp b/web/format/top_content.jsp index f500125..8f1aef0 100644 --- a/web/format/top_content.jsp +++ b/web/format/top_content.jsp @@ -51,4 +51,4 @@ <% } // end for %> <% } else { %> <%= rdat.getStdFontTag(null,2) %>No front page postings found. -<% } // end if %> \ No newline at end of file +<% } // end if %> diff --git a/web/format/topics.jsp b/web/format/topics.jsp index ada14c9..75dd2c9 100644 --- a/web/format/topics.jsp +++ b/web/format/topics.jsp @@ -190,4 +190,3 @@ ] -<% rdat.writeFooter(out); %> diff --git a/web/format/userprofile.jsp b/web/format/userprofile.jsp index ed4c6ba..d11c55c 100644 --- a/web/format/userprofile.jsp +++ b/web/format/userprofile.jsp @@ -109,5 +109,3 @@ <% } // end if %> - -<% rdat.writeFooter(out); %> diff --git a/web/images/sw-main.gif b/web/images/sw-main.gif new file mode 100644 index 0000000..6a1d4e2 Binary files /dev/null and b/web/images/sw-main.gif differ diff --git a/web/images/venicelogo.jpg b/web/images/venicelogo.jpg new file mode 100644 index 0000000..7759b83 Binary files /dev/null and b/web/images/venicelogo.jpg differ diff --git a/web/static/about-venice.html b/web/static/about-venice.html new file mode 100644 index 0000000..865965f --- /dev/null +++ b/web/static/about-venice.html @@ -0,0 +1,43 @@ + + + + About Venice + + + +
Venice Web Communities System

+

Venice Web Communities System Release 0.01PR

+ + Copyright © 2001 Silverwrist Design Studios, All Rights Reserved.

+ This software is subject to the + Mozilla Public License Version 1.1. + It 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 Venice Project Team

+
+
Eric Bowersox <erbo>
+
Code wrangler, system guru, and administrator in general
+
Harry Pike <maddog>
+
EMinds host and domain expert in virtual community hosting
+
Finnegan <finnegan>
+
Designer of the Venice web site
+
Catherine Dodson <cait>
+
Technical documentation
+
Pamela Boulais <silverwrist>
+
Administrative support, liaison, and den mother
+
The Entire Electric Minds Community
+
Beta testing, bug hunting, and encouragement
+
+ +
+ Thanks to: Howard, who thought it up; Andre, who rescued it the first time; and the community, who + kept it together no matter what. +

+ +

Silverwrist Design Studios
+ + + diff --git a/web/static/images/sw-main.gif b/web/static/images/sw-main.gif new file mode 100644 index 0000000..6a1d4e2 Binary files /dev/null and b/web/static/images/sw-main.gif differ diff --git a/web/static/images/venicelogo.jpg b/web/static/images/venicelogo.jpg new file mode 100644 index 0000000..7759b83 Binary files /dev/null and b/web/static/images/venicelogo.jpg differ