diff --git a/setup/database.sql b/setup/database.sql
index 49c65be..0aeca4a 100644
--- a/setup/database.sql
+++ b/setup/database.sql
@@ -44,6 +44,13 @@ CREATE TABLE globals (
sig_create_lvl INT NOT NULL
);
+# The global properties table. The "ndx" parameter is used to indicate what
+# element is being loaded, and then the "data" element is parsed.
+CREATE TABLE propglobal (
+ ndx INT NOT NULL PRIMARY KEY,
+ data VARCHAR(255)
+);
+
# The audit records table. Most "major" events add a record to this table.
CREATE TABLE audit (
record BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
@@ -93,6 +100,15 @@ CREATE TABLE userprefs (
localeid VARCHAR(64) DEFAULT 'en_US'
);
+# The per-user properties table. The "ndx" parameter is used to indicate what
+# element is being loaded, and then the "data" element is parsed.
+CREATE TABLE propuser (
+ uid INT NOT NULL,
+ ndx INT NOT NULL,
+ data VARCHAR(255),
+ PRIMARY KEY (uid, ndx)
+);
+
# Indicates what the top-level "sidebox" configuration is for any given user.
CREATE TABLE sideboxes (
uid INT NOT NULL,
@@ -238,6 +254,15 @@ CREATE TABLE sigban (
PRIMARY KEY (sigid, uid)
);
+# The community properties table. The "index" parameter is used to indicate what
+# element is being loaded, and then the "data" element is parsed.
+CREATE TABLE propcomm (
+ cid INT NOT NULL,
+ ndx INT NOT NULL,
+ data VARCHAR(255),
+ PRIMARY KEY (cid, ndx)
+);
+
# The table describing conferences. Like original CW, confs may be linked to more
# than one SIG.
CREATE TABLE confs (
@@ -306,6 +331,15 @@ CREATE TABLE confhotlist (
INDEX inorder (uid, sequence)
);
+# The conference properties table. The "index" parameter is used to indicate what
+# element is being loaded, and then the "data" element is parsed.
+CREATE TABLE propconf (
+ confid INT NOT NULL,
+ ndx INT NOT NULL,
+ data VARCHAR(255),
+ PRIMARY KEY (confid, ndx)
+);
+
# The table describing topics within a conference.
CREATE TABLE topics (
topicid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
@@ -1372,12 +1406,17 @@ INSERT INTO globals (posts_per_page, old_posts_at_top, max_search_page, max_sig_
fp_posts, num_audit_page, sig_create_lvl)
VALUES (20, 2, 20, 50, 50, 10, 100, 1000);
+# Initialize the global properies table.
+INSERT INTO propglobal (ndx, data)
+ VALUES (0, '');
+
# Add the 'Anonymous Honyak' user to the users table.
# (Do 'SELECT * FROM users WHERE is_anon = 1' to retrieve the AC user details.)
# (UID = 1, CONTACTID = 1)
INSERT INTO users (uid, username, passhash, contactid, is_anon, verify_email, base_lvl, created)
VALUES (1, 'Anonymous_Honyak', '', 1, 1, 1, 100, '2000-12-01 00:00:00');
INSERT INTO userprefs (uid) VALUES (1);
+INSERT INTO propuser (uid, ndx, data) VALUES (1, 0, '');
INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcode, country, email, owner_uid)
VALUES (1, 'Anonymous', 'User', 'Anywhere', '', '', 'US', 'nobody@example.com', 1);
@@ -1393,6 +1432,7 @@ INSERT INTO confhotlist (uid, sequence, sigid, confid)
INSERT INTO users (uid, username, passhash, contactid, verify_email, base_lvl, created)
VALUES (2, 'Administrator', '', 2, 1, 64999, '2000-12-01 00:00:00');
INSERT INTO userprefs (uid) VALUES (2);
+INSERT INTO propuser (uid, ndx, data) VALUES (2, 0, '');
INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcode, country, email, owner_uid)
VALUES (2, 'System', 'Administrator', 'Anywhere', '', '', 'US', 'root@your.box.com', 2);
@@ -1412,6 +1452,7 @@ INSERT INTO sigs (sigid, createdate, read_lvl, write_lvl, create_lvl, delete_lvl
'Admin');
INSERT INTO contacts (contactid, locality, country, owner_uid, owner_sigid)
VALUES (3, 'Anywhere', 'US', 2, 1);
+INSERT INTO propcomm (cid, ndx, data) VALUES (1, 0, '');
# Insert the desired features for the 'Administration' SIG.
INSERT INTO sigftrs (sigid, ftr_code)
@@ -1430,6 +1471,7 @@ INSERT INTO confs (confid, createdate, read_lvl, post_lvl, create_lvl, hide_lvl,
'Administrative Notes', 'Used to store notes and discussions between the site administrators.');
INSERT INTO sigtoconf (sigid, confid, sequence) VALUES (1, 1, 10);
INSERT INTO confalias (confid, alias) VALUES (1, 'Admin_Notes');
+INSERT INTO propconf (confid, ndx, data) VALUES (1, 0, '');
# Make the Administrator the host-of-record of the "Administrative Notes" conference.
INSERT INTO confmember (confid, uid, granted_lvl) VALUES (1, 2, 52500);
@@ -1444,6 +1486,7 @@ INSERT INTO sigs (sigid, createdate, read_lvl, write_lvl, create_lvl, delete_lvl
'Like the man said, do unto others as you would have them do unto you.', 'Piazza');
INSERT INTO contacts (contactid, locality, country, owner_uid, owner_sigid)
VALUES (4, 'Anywhere', 'US', 2, 2);
+INSERT INTO propcomm (cid, ndx, data) VALUES (2, 0, '');
# Insert the desired features for La Piazza.
INSERT INTO sigftrs (sigid, ftr_code)
@@ -1467,6 +1510,7 @@ INSERT INTO confs (confid, createdate, read_lvl, post_lvl, create_lvl, hide_lvl,
'Your place for general discussion about the system and general topics.');
INSERT INTO sigtoconf (sigid, confid, sequence) VALUES (2, 2, 10);
INSERT INTO confalias (confid, alias) VALUES (2, 'General');
+INSERT INTO propconf (confid, ndx, data) VALUES (2, 0, '');
# Make the Administrator the host-of-record of the "General Discussion" conference.
INSERT INTO confmember (confid, uid, granted_lvl) VALUES (2, 2, 52500);
@@ -1479,6 +1523,7 @@ INSERT INTO confs (confid, createdate, read_lvl, post_lvl, create_lvl, hide_lvl,
'Use this conference to test the conferencing system.');
INSERT INTO sigtoconf (sigid, confid, sequence) VALUES (2, 3, 20);
INSERT INTO confalias (confid, alias) VALUES (3, 'Test');
+INSERT INTO propconf (confid, ndx, data) VALUES (3, 0, '');
# Make the Administrator the host-of-record of the "Test Postings" conference.
INSERT INTO confmember (confid, uid, granted_lvl) VALUES (3, 2, 52500);
@@ -1492,6 +1537,7 @@ INSERT INTO confmember (confid, uid, granted_lvl) VALUES (3, 2, 52500);
INSERT INTO users (uid, username, passhash, contactid, verify_email, base_lvl, created)
VALUES (3, 'TestUser', '6BC1E91CF2917BE1AA0D0D1007C28437D3D3AEDF', 5, 1, 1000, '2000-12-01 00:00:00');
INSERT INTO userprefs (uid) VALUES (3);
+INSERT INTO propuser (uid, ndx, data) VALUES (3, 0, '');
INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcode, country, email, owner_uid)
VALUES (5, 'Test', 'User', 'Denver', 'CO', '80231', 'US', 'testuser@example.com', 3);
INSERT INTO sideboxes (uid, boxid, sequence, param)
@@ -1510,6 +1556,7 @@ INSERT INTO sigs (sigid, createdate, read_lvl, write_lvl, create_lvl, delete_lvl
'You must have a silly walk.', 'sillywalk');
INSERT INTO contacts (contactid, locality, country, owner_uid, owner_sigid)
VALUES (6, 'Anywhere', 'US', 2, 3);
+INSERT INTO propcomm (cid, ndx, data) VALUES (3, 0, '');
INSERT INTO sigftrs (sigid, ftr_code)
VALUES (3, 0), (3, 1), (3, 3);
INSERT INTO sigmember (sigid, uid, granted_lvl, locked)
@@ -1524,6 +1571,7 @@ INSERT INTO sigs (sigid, createdate, read_lvl, write_lvl, create_lvl, delete_lvl
'Evil Geniuses Only!', 'fnord', 'illuminati');
INSERT INTO contacts (contactid, locality, country, owner_uid, owner_sigid)
VALUES (7, 'Anywhere', 'US', 2, 4);
+INSERT INTO propcomm (cid, ndx, data) VALUES (4, 0, '');
INSERT INTO sigftrs (sigid, ftr_code)
VALUES (4, 0), (4, 1), (4, 3);
INSERT INTO sigmember (sigid, uid, granted_lvl, locked)
diff --git a/src/com/silverwrist/util/OptionSet.java b/src/com/silverwrist/util/OptionSet.java
index dd5c093..bf43b73 100644
--- a/src/com/silverwrist/util/OptionSet.java
+++ b/src/com/silverwrist/util/OptionSet.java
@@ -109,6 +109,19 @@ public class OptionSet extends BitSet
*--------------------------------------------------------------------------------
*/
+ public boolean assign(int ndx, boolean val)
+ {
+ if (ndx>=ALPHA.length())
+ throw new IndexOutOfBoundsException();
+ boolean old = super.get(ndx);
+ if (val)
+ super.set(ndx);
+ else
+ super.clear(ndx);
+ return (old!=val);
+
+ } // end assign
+
public void assign(char[] options)
{
int i;
@@ -127,7 +140,8 @@ public class OptionSet extends BitSet
public void assign(String options)
{
- assign(options.toCharArray());
+ if (options!=null)
+ assign(options.toCharArray());
} // end assign
diff --git a/src/com/silverwrist/venice/core/AdminOperations.java b/src/com/silverwrist/venice/core/AdminOperations.java
index 89038a1..51ebf91 100644
--- a/src/com/silverwrist/venice/core/AdminOperations.java
+++ b/src/com/silverwrist/venice/core/AdminOperations.java
@@ -31,4 +31,8 @@ public interface AdminOperations
public abstract AdminUserContext getUserContext(String username) throws DataException;
+ public abstract GlobalProperties getProperties();
+
+ public abstract void setProperties(GlobalProperties props) throws DataException;
+
} // end interface AdminOperations
diff --git a/src/com/silverwrist/venice/core/CommunityContext.java b/src/com/silverwrist/venice/core/CommunityContext.java
index 3351250..8ff8c14 100644
--- a/src/com/silverwrist/venice/core/CommunityContext.java
+++ b/src/com/silverwrist/venice/core/CommunityContext.java
@@ -171,4 +171,8 @@ public interface CommunityContext extends SearchMode
public abstract int getAuditRecordCount() throws AccessError, DataException;
+ public abstract CommunityProperties getProperties() throws DataException, AccessError;
+
+ public abstract void setProperties(CommunityProperties props) throws DataException, AccessError;
+
} // end interface CommunityContext
diff --git a/src/com/silverwrist/venice/core/CommunityProperties.java b/src/com/silverwrist/venice/core/CommunityProperties.java
new file mode 100644
index 0000000..480110b
--- /dev/null
+++ b/src/com/silverwrist/venice/core/CommunityProperties.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.core;
+
+public final class CommunityProperties
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private boolean display_post_pictures;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public CommunityProperties()
+ {
+ display_post_pictures = false;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Public getters/setters
+ *--------------------------------------------------------------------------------
+ */
+
+ public final boolean getDisplayPostPictures()
+ {
+ return display_post_pictures;
+
+ } // end getDisplayPostPictures
+
+ public final void setDisplayPostPictures(boolean b)
+ {
+ display_post_pictures = b;
+
+ } // end setDisplayPostPictures
+
+} // end class CommunityProperties
diff --git a/src/com/silverwrist/venice/core/ConferenceContext.java b/src/com/silverwrist/venice/core/ConferenceContext.java
index f49550e..30a7feb 100644
--- a/src/com/silverwrist/venice/core/ConferenceContext.java
+++ b/src/com/silverwrist/venice/core/ConferenceContext.java
@@ -153,4 +153,10 @@ public interface ConferenceContext
public abstract void setHotlistSequence(int seq) throws DataException;
+ public abstract boolean displayPostPictures();
+
+ public abstract ConferenceProperties getProperties() throws DataException, AccessError;
+
+ public abstract void setProperties(ConferenceProperties props) throws DataException, AccessError;
+
} // end interface ConferenceContext
diff --git a/src/com/silverwrist/venice/core/ConferenceProperties.java b/src/com/silverwrist/venice/core/ConferenceProperties.java
new file mode 100644
index 0000000..10f3673
--- /dev/null
+++ b/src/com/silverwrist/venice/core/ConferenceProperties.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.core;
+
+public final class ConferenceProperties
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private boolean display_post_pictures;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public ConferenceProperties()
+ {
+ display_post_pictures = false;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Public getters/setters
+ *--------------------------------------------------------------------------------
+ */
+
+ public final boolean getDisplayPostPictures()
+ {
+ return display_post_pictures;
+
+ } // end getDisplayPostPictures
+
+ public final void setDisplayPostPictures(boolean b)
+ {
+ display_post_pictures = b;
+
+ } // end setDisplayPostPictures
+
+} // end class ConferenceProperties
diff --git a/src/com/silverwrist/venice/core/GlobalProperties.java b/src/com/silverwrist/venice/core/GlobalProperties.java
new file mode 100644
index 0000000..fe0db42
--- /dev/null
+++ b/src/com/silverwrist/venice/core/GlobalProperties.java
@@ -0,0 +1,169 @@
+/*
+ * 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.core;
+
+public final class GlobalProperties
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private int posts_per_page;
+ private int old_posts_at_top;
+ private int search_items_per_page;
+ private int community_members_per_page;
+ private int conference_members_per_page;
+ private int posts_on_front_page;
+ private int audit_records_per_page;
+ private int community_create_level;
+ private boolean display_post_pictures;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public GlobalProperties()
+ {
+ posts_per_page = 20;
+ old_posts_at_top = 2;
+ search_items_per_page = 20;
+ community_members_per_page = 50;
+ conference_members_per_page = 50;
+ posts_on_front_page = 10;
+ audit_records_per_page = 100;
+ community_create_level = com.silverwrist.venice.security.SecLevels.GLOBAL_NORMAL;
+ display_post_pictures = false;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Public getters/setters
+ *--------------------------------------------------------------------------------
+ */
+
+ public final int getPostsPerPage()
+ {
+ return posts_per_page;
+
+ } // end getPostsPerPage
+
+ public final void setPostsPerPage(int v)
+ {
+ posts_per_page = v;
+
+ } // end setPostsPerPage
+
+ public final int getOldPostsAtTop()
+ {
+ return old_posts_at_top;
+
+ } // end getOldPostsAtTop
+
+ public final void setOldPostsAtTop(int v)
+ {
+ old_posts_at_top = v;
+
+ } // end setOldPostsAtTop
+
+ public final int getSearchItemsPerPage()
+ {
+ return search_items_per_page;
+
+ } // end getSearchItemsPerPage
+
+ public final void setSearchItemsPerPage(int v)
+ {
+ search_items_per_page = v;
+
+ } // end setSearchItemsPerPage
+
+ public final int getCommunityMembersPerPage()
+ {
+ return community_members_per_page;
+
+ } // end getCommunityMembersPerPage
+
+ public final void setCommunityMembersPerPage(int v)
+ {
+ community_members_per_page = v;
+
+ } // end setCommunityMembersPerPage
+
+ public final int getConferenceMembersPerPage()
+ {
+ return conference_members_per_page;
+
+ } // end getConferenceMembersPerPage
+
+ public final void setConferenceMembersPerPage(int v)
+ {
+ conference_members_per_page = v;
+
+ } // end setConferenceMembersPerPage
+
+ public final int getPostsOnFrontPage()
+ {
+ return posts_on_front_page;
+
+ } // end getPostsOnFontPage
+
+ public final void setPostsOnFrontPage(int v)
+ {
+ posts_on_front_page = v;
+
+ } // end setPostsOnFrontPage
+
+ public final int getAuditRecordsPerPage()
+ {
+ return audit_records_per_page;
+
+ } // end getAuditRecordsPerPage
+
+ public final void setAuditRecordsPerPage(int v)
+ {
+ audit_records_per_page = v;
+
+ } // end setAuditRecordsPerPage
+
+ public final int getCommunityCreateLevel()
+ {
+ return community_create_level;
+
+ } // end getCommunityCreateLevel
+
+ public final void setCommunityCreateLevel(int v)
+ {
+ community_create_level = v;
+
+ } // end setCommunityCreateLevel
+
+ public final boolean getDisplayPostPictures()
+ {
+ return display_post_pictures;
+
+ } // end getDisplayPostPictures
+
+ public final void setDisplayPostPictures(boolean b)
+ {
+ display_post_pictures = b;
+
+ } // end setDisplayPostPictures
+
+} // end class GlobalProperties
diff --git a/src/com/silverwrist/venice/core/UserContext.java b/src/com/silverwrist/venice/core/UserContext.java
index 250dc2a..8c56ca5 100644
--- a/src/com/silverwrist/venice/core/UserContext.java
+++ b/src/com/silverwrist/venice/core/UserContext.java
@@ -112,4 +112,10 @@ public interface UserContext extends SearchMode
public abstract Advertisement selectAd();
+ public abstract boolean displayPostPictures() throws DataException;
+
+ public abstract UserProperties getProperties() throws DataException;
+
+ public abstract void setProperties(UserProperties props) throws DataException;
+
} // end interface UserContext
diff --git a/src/com/silverwrist/venice/core/UserProperties.java b/src/com/silverwrist/venice/core/UserProperties.java
new file mode 100644
index 0000000..21cd1f1
--- /dev/null
+++ b/src/com/silverwrist/venice/core/UserProperties.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.core;
+
+public final class UserProperties
+{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private boolean display_post_pictures;
+
+ /*--------------------------------------------------------------------------------
+ * Constructor
+ *--------------------------------------------------------------------------------
+ */
+
+ public UserProperties()
+ {
+ display_post_pictures = false;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Public getters/setters
+ *--------------------------------------------------------------------------------
+ */
+
+ public final boolean getDisplayPostPictures()
+ {
+ return display_post_pictures;
+
+ } // end getDisplayPostPictures
+
+ public final void setDisplayPostPictures(boolean b)
+ {
+ display_post_pictures = b;
+
+ } // end setDisplayPostPictures
+
+} // end class UserProperties
diff --git a/src/com/silverwrist/venice/core/impl/AdminOperationsImpl.java b/src/com/silverwrist/venice/core/impl/AdminOperationsImpl.java
index 02a6368..c96143f 100644
--- a/src/com/silverwrist/venice/core/impl/AdminOperationsImpl.java
+++ b/src/com/silverwrist/venice/core/impl/AdminOperationsImpl.java
@@ -135,4 +135,16 @@ class AdminOperationsImpl implements AdminOperations
} // end getUserContext
+ public GlobalProperties getProperties()
+ {
+ return engine.getProperties();
+
+ } // end getProperties
+
+ public void setProperties(GlobalProperties props) throws DataException
+ {
+ engine.setProperties(props);
+
+ } // end setProperties
+
} // end class AdminOperationsImpl
diff --git a/src/com/silverwrist/venice/core/impl/BackgroundCommunityPurge.java b/src/com/silverwrist/venice/core/impl/BackgroundCommunityPurge.java
index 4bc7c4c..ae8e981 100644
--- a/src/com/silverwrist/venice/core/impl/BackgroundCommunityPurge.java
+++ b/src/com/silverwrist/venice/core/impl/BackgroundCommunityPurge.java
@@ -88,6 +88,7 @@ class BackgroundCommunityPurge implements Runnable
stmt.executeUpdate("DELETE FROM contacts WHERE owner_sigid = " + cid + ";");
stmt.executeUpdate("DELETE FROM sigftrs WHERE sigid = " + cid + ";");
stmt.executeUpdate("DELETE FROM sigban WHERE sigid = " + cid + ";");
+ stmt.executeUpdate("DELETE FROM propcomm WHERE cid = " + cid + ";");
// look up all conference IDs in this community
int[] conf_ids = new int[num_confs];
@@ -132,6 +133,7 @@ class BackgroundCommunityPurge implements Runnable
// tables first
stmt.executeUpdate("DELETE FROM confs WHERE confid = " + key + ";");
stmt.executeUpdate("DELETE FROM confalias WHERE confid = " + key + ";");
+ stmt.executeUpdate("DELETE FROM propconf WHERE confid = " + key + ";");
// determine the number of topics in this conference, and the maximum topic ID, and use
// that information to queue up the conference deletion
diff --git a/src/com/silverwrist/venice/core/impl/BackgroundConferencePurge.java b/src/com/silverwrist/venice/core/impl/BackgroundConferencePurge.java
index 3450d2e..bdb0410 100644
--- a/src/com/silverwrist/venice/core/impl/BackgroundConferencePurge.java
+++ b/src/com/silverwrist/venice/core/impl/BackgroundConferencePurge.java
@@ -81,7 +81,7 @@ class BackgroundConferencePurge implements Runnable
stmt.executeUpdate("DELETE FROM confmember WHERE confid = " + confid + ";");
stmt.executeUpdate("DELETE FROM confsettings WHERE confid = " + confid + ";");
stmt.executeUpdate("DELETE FROM confhotlist WHERE confid = " + confid + ";");
- stmt.executeUpdate("DELETE FROM confbozo WHERE confid = " + confid + ";");
+ stmt.executeUpdate("DELETE FROM propconf WHERE confid = " + confid + ";");
// look up all the topic IDs that are present in this conference
int[] topicids = new int[num_topics];
diff --git a/src/com/silverwrist/venice/core/impl/CommunityBackend.java b/src/com/silverwrist/venice/core/impl/CommunityBackend.java
index da45b8d..d53761c 100644
--- a/src/com/silverwrist/venice/core/impl/CommunityBackend.java
+++ b/src/com/silverwrist/venice/core/impl/CommunityBackend.java
@@ -40,4 +40,6 @@ public interface CommunityBackend extends UserBackend
public abstract boolean userCanDeleteSubobjects();
+ public abstract CommunityDataBackend getDataBackend() throws DataException;
+
} // end interface CommunityBackend
diff --git a/src/com/silverwrist/venice/core/impl/CommunityCoreData.java b/src/com/silverwrist/venice/core/impl/CommunityCoreData.java
index a13c6e8..847b7b5 100644
--- a/src/com/silverwrist/venice/core/impl/CommunityCoreData.java
+++ b/src/com/silverwrist/venice/core/impl/CommunityCoreData.java
@@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
+import com.silverwrist.util.OptionSet;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.rcache.*;
import com.silverwrist.venice.db.*;
@@ -64,6 +65,11 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
*--------------------------------------------------------------------------------
*/
+ // Property indices
+ private static final int PROP_FLAGS = 0; // flags
+
+ private static final BitSet ALL_PROPS; // BitSet representing all properties
+
private static Category logger = Category.getInstance(CommunityCoreData.class);
/*--------------------------------------------------------------------------------
@@ -101,6 +107,7 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
private ReferenceCache conf_refcache = new ReferenceCache();
private ConferenceCommunityContextImplCreator conf_creator = new ConferenceCommunityContextImplCreator();
private boolean deleted = false; // has this community been deleted?
+ private OptionSet flags; // property flags
/*--------------------------------------------------------------------------------
* Constructor
@@ -131,6 +138,24 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
loadData(rs); // load the community data
+ sql.setLength(0);
+ sql.append("SELECT ndx, data FROM propcomm WHERE cid = ").append(cid).append(';');
+ rs = stmt.executeQuery(sql.toString());
+ while (rs.next())
+ { // load all properties
+ switch (rs.getInt(1))
+ { // look for the various property indices
+ case PROP_FLAGS:
+ flags = new OptionSet(rs.getString(2));
+ break;
+
+ default:
+ break;
+
+ } // end switch
+
+ } // end while
+
// get the community feature set
sql.setLength(0);
sql.append("SELECT ftr_code FROM sigftrs WHERE sigid = ").append(cid).append(';');
@@ -188,6 +213,9 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
this.alias = alias;
this.public_comm = StringUtil.isStringEmpty(joinkey);
this.features = (BitSet)(features.clone());
+ this.flags = new OptionSet();
+ if (engine.getParamBoolean(EngineBackend.BP_POSTPICTURES))
+ flags.set(BP_POSTPICTURES);
} // end constructor
@@ -266,6 +294,81 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
} // end touchUpdate
+ private void newProperties(Connection conn) throws SQLException
+ {
+ // generate start of SQL statement
+ Statement stmt = conn.createStatement();
+ StringBuffer sql = new StringBuffer("INSERT INTO propcomm (cid, ndx, data) VALUES ");
+
+ // append Property 0: flags
+ sql.append('(').append(cid).append(", ").append(PROP_FLAGS).append(", '");
+ sql.append(flags.asString()).append("')");
+
+ // finish up
+ sql.append(';');
+ stmt.executeUpdate(sql.toString());
+
+ } // end newProperties
+
+ private synchronized void updateProperties(BitSet delta) throws DataException
+ {
+ Connection conn = null;
+ try
+ { // get a connection and create a statement
+ conn = datapool.getConnection();
+ Statement stmt = conn.createStatement();
+ StringBuffer sql = new StringBuffer();
+
+ if (delta.get(PROP_FLAGS))
+ { // store the flags
+ sql.append("UPDATE propcomm SET data = '").append(flags.asString()).append("' WHERE cid = ");
+ sql.append(cid).append(" AND ndx = ").append(PROP_FLAGS).append(';');
+ stmt.executeUpdate(sql.toString());
+ sql.setLength(0);
+
+ } // end if
+
+ } // end try
+ catch (SQLException e)
+ { // database error - this is a DataException
+ logger.error("DB error storing community properties: " + e.getMessage(),e);
+ throw new DataException("unable to save community properties: " + e.getMessage(),e);
+
+ } // end catch
+ finally
+ { // make sure the connection is released before we go
+ if (conn!=null)
+ datapool.releaseConnection(conn);
+
+ } // end finally
+
+ } // end updateProperties
+
+ private synchronized void updateProperties() throws DataException
+ {
+ updateProperties(ALL_PROPS);
+
+ } // end updateProperties
+
+ private final CommunityProperties createProperties()
+ {
+ CommunityProperties rc = new CommunityProperties();
+ rc.setDisplayPostPictures(flags.get(BP_POSTPICTURES));
+ return rc;
+
+ } // end createProperties
+
+ private final synchronized BitSet storeProperties(CommunityProperties props)
+ {
+ BitSet rc = new BitSet();
+
+ if (flags.assign(BP_POSTPICTURES,props.getDisplayPostPictures()))
+ rc.set(PROP_FLAGS);
+
+ return rc;
+
+ } // end storeProperties
+
/*--------------------------------------------------------------------------------
* Implementations from interface ReferencedData
*--------------------------------------------------------------------------------
@@ -1886,6 +1989,35 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
} // end sweepCache
+ public CommunityProperties getProperties()
+ {
+ return createProperties();
+
+ } // end getProperties
+
+ public void setProperties(CommunityProperties props) throws DataException
+ {
+ CommunityProperties orig = createProperties();
+ BitSet delta = storeProperties(props);
+ if (delta.length()==0)
+ return;
+
+ boolean succeeded = false;
+ try
+ { // update the properties in the database
+ updateProperties(delta);
+ succeeded = true;
+
+ } // end try
+ finally
+ { // make sure the connection is released before we go
+ if (!succeeded)
+ storeProperties(orig);
+
+ } // end finally
+
+ } // end setProperties
+
/*--------------------------------------------------------------------------------
* Implementations from interface CommunityDataBackend
*--------------------------------------------------------------------------------
@@ -1897,6 +2029,12 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
} // end realCommunityID
+ public boolean getParamBoolean(int selector)
+ {
+ return flags.get(selector);
+
+ } // end getParamBoolean
+
/*--------------------------------------------------------------------------------
* External static operations (usable only from within package)
*--------------------------------------------------------------------------------
@@ -1912,12 +2050,13 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
int new_cid; // ID of the new community
java.util.Date creation; // creation date!
AuditRecord ar = null; // the audit record
+ CommunityCoreData comm; // the new community that gets returned
try
{ // get a database connection and create the appropriate SELECT statement
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
- stmt.executeUpdate("LOCK TABLES sigs WRITE, sigftrs WRITE, sigmember WRITE;");
+ stmt.executeUpdate("LOCK TABLES sigs WRITE, sigftrs WRITE, propcomm WRITE, sigmember WRITE;");
try
{ // first, we need to check if the community alias already exists
@@ -1997,6 +2136,12 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
logger.debug("SQL: " + sql.toString());
stmt.executeUpdate(sql.toString());
+ // Create the CommunityCoreData object representing this community and register it with the engine's
+ // community data object cache.
+ comm = new CommunityCoreData(engine,datapool,new_cid,creation,name,alias,host_uid,language,synopsis,
+ rules,joinkey,hide_dir,hide_search,def_features);
+ comm.newProperties(conn);
+
} // end try
finally
{ // unlock the tables before we bail out
@@ -2005,10 +2150,12 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
} // end finally
+ engine.registerNewCommunity(comm);
+
// create an audit record indicating we were successful
ar = new AuditRecord(AuditRecord.CREATE_COMMUNITY,host_uid,user.userRemoteAddress(),new_cid,
"name=" + name,"alias=" + alias);
-
+
} // end try
catch (SQLException e)
{ // database error - this is a DataException
@@ -2035,14 +2182,21 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
} // end finally
- // Create the CommunityCoreData object representing this community and register it with the engine's
- // community data object cache.
- CommunityCoreData comm = new CommunityCoreData(engine,datapool,new_cid,creation,name,alias,host_uid,
- language,synopsis,rules,joinkey,hide_dir,hide_search,
- def_features);
- engine.registerNewCommunity(comm);
return comm;
} // end createCommunity
+ /*--------------------------------------------------------------------------------
+ * Static initializer
+ *--------------------------------------------------------------------------------
+ */
+
+ static
+ { // initialize the "all properties" bit set
+ BitSet tmp = new BitSet();
+ tmp.set(PROP_FLAGS);
+ ALL_PROPS = tmp;
+
+ } // end static initializer
+
} // end class CommunityCoreData
diff --git a/src/com/silverwrist/venice/core/impl/CommunityData.java b/src/com/silverwrist/venice/core/impl/CommunityData.java
index 67ee296..33b4237 100644
--- a/src/com/silverwrist/venice/core/impl/CommunityData.java
+++ b/src/com/silverwrist/venice/core/impl/CommunityData.java
@@ -22,6 +22,7 @@ import java.util.Date;
import java.util.List;
import com.silverwrist.util.rcache.ReferencedData;
import com.silverwrist.venice.core.AccessError;
+import com.silverwrist.venice.core.CommunityProperties;
import com.silverwrist.venice.core.ContactInfo;
import com.silverwrist.venice.core.DataException;
@@ -154,4 +155,8 @@ public interface CommunityData extends ReferencedData
public abstract void sweepCache();
+ public abstract CommunityProperties getProperties();
+
+ public abstract void setProperties(CommunityProperties props) throws DataException;
+
} // end interface CommunityData
diff --git a/src/com/silverwrist/venice/core/impl/CommunityDataBackend.java b/src/com/silverwrist/venice/core/impl/CommunityDataBackend.java
index 7114444..3a85aba 100644
--- a/src/com/silverwrist/venice/core/impl/CommunityDataBackend.java
+++ b/src/com/silverwrist/venice/core/impl/CommunityDataBackend.java
@@ -19,6 +19,11 @@ package com.silverwrist.venice.core.impl;
public interface CommunityDataBackend
{
+ // Boolean parameter indexes
+ public static final int BP_POSTPICTURES = 0;
+
public abstract int realCommunityID();
+ public abstract boolean getParamBoolean(int selector);
+
} // end interface CommunityDataBackend
diff --git a/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java b/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java
index d47b6dc..9f8e502 100644
--- a/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java
+++ b/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java
@@ -1361,6 +1361,36 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend
} // end getAuditRecordCount
+ public CommunityProperties getProperties() throws DataException, AccessError
+ {
+ getData().testMembership(level,is_member);
+ if (!(getData().canModifyCommunityProfile(level)))
+ { // this user can't modify the community feature set
+ logger.error("user not permitted to modify the community's information");
+ throw new AccessError("You are not permitted to modify the community's information.");
+
+ } // end if
+
+ // call down to do it
+ return getData().getProperties();
+
+ } // end getProperties
+
+ public void setProperties(CommunityProperties props) throws DataException, AccessError
+ {
+ getData().testMembership(level,is_member);
+ if (!(getData().canModifyCommunityProfile(level)))
+ { // this user can't modify the community feature set
+ logger.error("user not permitted to modify the community's information");
+ throw new AccessError("You are not permitted to modify the community's information.");
+
+ } // end if
+
+ // call down to do it
+ getData().setProperties(props);
+
+ } // end setProperties
+
/*--------------------------------------------------------------------------------
* Implementations from interface UserBackend
*--------------------------------------------------------------------------------
@@ -1485,6 +1515,12 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend
} // end userCanDeleteSubobjects
+ public CommunityDataBackend getDataBackend() throws DataException
+ {
+ return (CommunityDataBackend)(getData());
+
+ } // end getDataBackend
+
/*--------------------------------------------------------------------------------
* Static operations for use within the implementation package
*--------------------------------------------------------------------------------
diff --git a/src/com/silverwrist/venice/core/impl/ConferenceCommunityContext.java b/src/com/silverwrist/venice/core/impl/ConferenceCommunityContext.java
index 1e6945e..4de21b9 100644
--- a/src/com/silverwrist/venice/core/impl/ConferenceCommunityContext.java
+++ b/src/com/silverwrist/venice/core/impl/ConferenceCommunityContext.java
@@ -21,6 +21,7 @@ import java.sql.Connection;
import java.util.Date;
import java.util.List;
import com.silverwrist.util.rcache.ReferencedData;
+import com.silverwrist.venice.core.ConferenceProperties;
import com.silverwrist.venice.core.DataException;
public interface ConferenceCommunityContext extends ReferencedData
@@ -109,4 +110,10 @@ public interface ConferenceCommunityContext extends ReferencedData
public abstract void delete(UserBackend user) throws DataException;
+ public abstract boolean displayPostPictures();
+
+ public abstract ConferenceProperties getProperties() throws DataException;
+
+ public abstract void setProperties(ConferenceProperties props) throws DataException;
+
} // end interface ConferenceCommunityContext
diff --git a/src/com/silverwrist/venice/core/impl/ConferenceCommunityContextImpl.java b/src/com/silverwrist/venice/core/impl/ConferenceCommunityContextImpl.java
index 3778e59..056207c 100644
--- a/src/com/silverwrist/venice/core/impl/ConferenceCommunityContextImpl.java
+++ b/src/com/silverwrist/venice/core/impl/ConferenceCommunityContextImpl.java
@@ -833,4 +833,26 @@ class ConferenceCommunityContextImpl implements ConferenceCommunityContext
} // end delete
+ public boolean displayPostPictures()
+ {
+ ConferenceData c = getConferenceDataNE();
+ if (c!=null)
+ return c.displayPostPictures();
+ else
+ return false;
+
+ } // end displayPostPictures
+
+ public ConferenceProperties getProperties() throws DataException
+ {
+ return getConferenceData().getProperties();
+
+ } // end getProperties
+
+ public void setProperties(ConferenceProperties props) throws DataException
+ {
+ getConferenceData().setProperties(props);
+
+ } // end setProperties
+
} // end class ConferenceCommunityContextImpl
diff --git a/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java b/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java
index 556be0e..5885182 100644
--- a/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java
+++ b/src/com/silverwrist/venice/core/impl/ConferenceCoreData.java
@@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
+import com.silverwrist.util.OptionSet;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.security.AuditRecord;
import com.silverwrist.venice.security.DefaultLevels;
@@ -32,6 +33,14 @@ class ConferenceCoreData implements ConferenceData
*--------------------------------------------------------------------------------
*/
+ // Property indexes
+ private static final int PROP_FLAGS = 0; // flags
+
+ private static final BitSet ALL_PROPS; // BitSet representing all properties
+
+ // Boolean property selectors
+ private static final int BP_POSTPICTURES = 0;
+
private static Category logger = Category.getInstance(ConferenceCoreData.class);
/*--------------------------------------------------------------------------------
@@ -58,6 +67,7 @@ class ConferenceCoreData implements ConferenceData
private String cached_alias = null; // the cached alias (for getAnAlias)
private boolean creating_topic = false; // is somebody creating a topic?
private boolean deleted = false; // has this conference been deleted?
+ private OptionSet flags; // option flags
/*--------------------------------------------------------------------------------
* Constructors
@@ -87,6 +97,8 @@ class ConferenceCoreData implements ConferenceData
throw new DataException("Conference #" + confid + " does not exist in the database.");
loadData(rs); // load the conference data
+ flags = new OptionSet();
+ loadProperties(conn);
} // end try
catch (SQLException e)
@@ -104,8 +116,8 @@ class ConferenceCoreData implements ConferenceData
} // end constructor
- protected ConferenceCoreData(EngineBackend engine, DataPool datapool, int confid, java.util.Date created,
- boolean pvt, String name, String descr)
+ protected ConferenceCoreData(EngineBackend engine, CommunityDataBackend comm, DataPool datapool, int confid,
+ java.util.Date created, boolean pvt, String name, String descr)
{
if (logger.isDebugEnabled())
logger.debug("new ConferenceCoreData for NEW conference " + confid);
@@ -124,6 +136,9 @@ class ConferenceCoreData implements ConferenceData
this.top_topic = 0;
this.name = name;
this.description = descr;
+ this.flags = new OptionSet();
+ if (comm.getParamBoolean(CommunityDataBackend.BP_POSTPICTURES))
+ flags.set(BP_POSTPICTURES);
} // end constructor
@@ -151,6 +166,29 @@ class ConferenceCoreData implements ConferenceData
} // end loadData
+ private synchronized void loadProperties(Connection conn) throws SQLException
+ {
+ Statement stmt = conn.createStatement();
+ StringBuffer sql = new StringBuffer("SELECT ndx, data FROM propconf WHERE confid = ");
+ sql.append(confid).append(';');
+ ResultSet rs = stmt.executeQuery(sql.toString());
+ while (rs.next())
+ { // load the property records one at a time
+ switch (rs.getInt(1))
+ { // figure out which properties to load
+ case PROP_FLAGS:
+ flags.assign(rs.getString(2));
+ break;
+
+ default:
+ break;
+
+ } // end switch
+
+ } // end while
+
+ } // end loadProperties
+
private synchronized void touchUpdate(Connection conn) throws SQLException
{
Statement stmt = conn.createStatement();
@@ -162,6 +200,80 @@ class ConferenceCoreData implements ConferenceData
} // end touchUpdate
+ private void newProperties(Connection conn) throws SQLException
+ {
+ Statement stmt = conn.createStatement();
+ StringBuffer sql = new StringBuffer("INSERT INTO propconf (confid, ndx, data) VALUES ");
+
+ // Append Property 0 - the "flags" property.
+ sql.append('(').append(confid).append(", ").append(PROP_FLAGS).append(", '");
+ sql.append(flags.asString()).append("')");
+
+ // Finish up.
+ sql.append(';');
+ stmt.executeUpdate(sql.toString());
+
+ } // end newProperties
+
+ private synchronized void updateProperties(BitSet delta) throws DataException
+ {
+ Connection conn = null;
+ try
+ { // get a connection and create a statement
+ conn = datapool.getConnection();
+ Statement stmt = conn.createStatement();
+ StringBuffer sql = new StringBuffer();
+
+ if (delta.get(PROP_FLAGS))
+ { // store the flags
+ sql.append("UPDATE propconf SET data = '").append(flags.asString()).append("' WHERE confid = ");
+ sql.append(confid).append(" AND ndx = ").append(PROP_FLAGS).append(';');
+ stmt.executeUpdate(sql.toString());
+ sql.setLength(0);
+
+ } // end if
+
+ } // end try
+ catch (SQLException e)
+ { // database error - this is a DataException
+ logger.error("DB error storing conference properties: " + e.getMessage(),e);
+ throw new DataException("unable to save conference properties: " + e.getMessage(),e);
+
+ } // end catch
+ finally
+ { // make sure the connection is released before we go
+ if (conn!=null)
+ datapool.releaseConnection(conn);
+
+ } // end finally
+
+ } // end updateProperties
+
+ private synchronized void updateProperties() throws DataException
+ {
+ updateProperties(ALL_PROPS);
+
+ } // end updateProperties
+
+ private final ConferenceProperties createProperties()
+ {
+ ConferenceProperties rc = new ConferenceProperties();
+ rc.setDisplayPostPictures(flags.get(BP_POSTPICTURES));
+ return rc;
+
+ } // end createProperties
+
+ private final synchronized BitSet storeProperties(ConferenceProperties props)
+ {
+ BitSet rc = new BitSet();
+
+ if (flags.assign(BP_POSTPICTURES,props.getDisplayPostPictures()))
+ rc.set(PROP_FLAGS);
+
+ return rc;
+
+ } // end storeProperties
+
/*--------------------------------------------------------------------------------
* Implementations from interface ReferencedData
*--------------------------------------------------------------------------------
@@ -1254,6 +1366,41 @@ class ConferenceCoreData implements ConferenceData
} // end delete
+ public boolean displayPostPictures()
+ {
+ return flags.get(BP_POSTPICTURES);
+
+ } // end displayPostPictures
+
+ public ConferenceProperties getProperties()
+ {
+ return createProperties();
+
+ } // end getProperties
+
+ public synchronized void setProperties(ConferenceProperties props) throws DataException
+ {
+ ConferenceProperties orig = createProperties();
+ BitSet delta = storeProperties(props);
+ if (delta.length()==0)
+ return;
+
+ boolean succeeded = false;
+ try
+ { // update the properties in the database
+ updateProperties(delta);
+ succeeded = true;
+
+ } // end try
+ finally
+ { // make sure the connection is released before we go
+ if (!succeeded)
+ storeProperties(orig);
+
+ } // end finally
+
+ } // end setProperties
+
/*--------------------------------------------------------------------------------
* External static operations (usable only from within package)
*--------------------------------------------------------------------------------
@@ -1263,11 +1410,13 @@ class ConferenceCoreData implements ConferenceData
String name, String alias, String description, boolean pvt,
boolean hide_list, int host_uid) throws DataException
{
+ CommunityDataBackend data_backend = comm.getDataBackend();
Connection conn = null; // database connection
AuditRecord ar = null; // audit record
int new_confid; // new conference ID
short new_sequence; // new sequence number
java.util.Date created; // date/time conference created
+ ConferenceCoreData conf; // returned conference core data
if (logger.isDebugEnabled())
logger.debug("createConference entry");
@@ -1276,7 +1425,8 @@ class ConferenceCoreData implements ConferenceData
{ // start by locking all the tables we need
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
- stmt.executeUpdate("LOCK TABLES confs WRITE, sigtoconf WRITE, confalias WRITE, confmember WRITE;");
+ stmt.executeUpdate("LOCK TABLES confs WRITE, sigtoconf WRITE, confalias WRITE, confmember WRITE, "
+ + "propconf WRITE;");
try
{ // first check on the alias availability
@@ -1347,6 +1497,11 @@ class ConferenceCoreData implements ConferenceData
logger.debug("SQL: " + sql.toString());
stmt.executeUpdate(sql.toString());
+ // Create a new ConferenceCoreData object representing this conference and register it with the
+ // engine's conference data object cache.
+ conf = new ConferenceCoreData(engine,data_backend,datapool,new_confid,created,pvt,name,description);
+ conf.newProperties(conn);
+
} // end try
finally
{ // unlock the tables before we go
@@ -1355,6 +1510,8 @@ class ConferenceCoreData implements ConferenceData
} // end finally
+ engine.registerNewConference(conf);
+
// create an audit record indicating we were successful
ar = new AuditRecord(AuditRecord.CREATE_CONF,comm.realUID(),comm.userRemoteAddress(),
comm.realCommunityID(),"confid=" + new_confid,"name=" + name,"alias=" + alias);
@@ -1385,12 +1542,21 @@ class ConferenceCoreData implements ConferenceData
} // end finally
- // Create a new ConferenceCoreData object representing this conference and register it with the
- // engine's conference data object cache.
- ConferenceCoreData conf = new ConferenceCoreData(engine,datapool,new_confid,created,pvt,name,description);
- engine.registerNewConference(conf);
return new ReturnConfSeq(conf,new_sequence);
} // end createConference
+ /*--------------------------------------------------------------------------------
+ * Static initializer
+ *--------------------------------------------------------------------------------
+ */
+
+ static
+ { // initialize the "all properties" bit set
+ BitSet tmp = new BitSet();
+ tmp.set(PROP_FLAGS);
+ ALL_PROPS = tmp;
+
+ } // end static initializer
+
} // end class ConferenceCoreData
diff --git a/src/com/silverwrist/venice/core/impl/ConferenceData.java b/src/com/silverwrist/venice/core/impl/ConferenceData.java
index 8a8d625..fac9132 100644
--- a/src/com/silverwrist/venice/core/impl/ConferenceData.java
+++ b/src/com/silverwrist/venice/core/impl/ConferenceData.java
@@ -21,6 +21,7 @@ import java.sql.Connection;
import java.util.Date;
import java.util.List;
import com.silverwrist.util.rcache.ReferencedData;
+import com.silverwrist.venice.core.ConferenceProperties;
import com.silverwrist.venice.core.DataException;
public interface ConferenceData extends ReferencedData
@@ -103,4 +104,10 @@ public interface ConferenceData extends ReferencedData
public abstract void delete(UserBackend user, int the_cid) throws DataException;
+ public abstract boolean displayPostPictures();
+
+ public abstract ConferenceProperties getProperties();
+
+ public abstract void setProperties(ConferenceProperties props) throws DataException;
+
} // end interface ConferenceData
diff --git a/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java b/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java
index ddf42c5..3cafeeb 100644
--- a/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java
+++ b/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java
@@ -1442,6 +1442,43 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end setHotlistSequence
+ public boolean displayPostPictures()
+ {
+ ConferenceCommunityContext c = getConferenceDataNE();
+ if (c==null)
+ return false;
+ return c.displayPostPictures();
+
+ } // end displayPostPictures
+
+ public ConferenceProperties getProperties() throws DataException, AccessError
+ {
+ if (!(getConferenceData().canChangeConference(level)))
+ { // this user can't modify the conference properties
+ logger.error("user not permitted to change properties");
+ throw new AccessError("You are not permitted to change the properties of this conference.");
+
+ } // end if
+
+ // call down to get the properties
+ return getConferenceData().getProperties();
+
+ } // end getProperties
+
+ public void setProperties(ConferenceProperties props) throws DataException, AccessError
+ {
+ if (!(getConferenceData().canChangeConference(level)))
+ { // this user can't modify the conference properties
+ logger.error("user not permitted to change properties");
+ throw new AccessError("You are not permitted to change the properties of this conference.");
+
+ } // end if
+
+ // call down to set the properties
+ getConferenceData().setProperties(props);
+
+ } // end setProperties
+
/*--------------------------------------------------------------------------------
* Implementations from interface UserBackend
*--------------------------------------------------------------------------------
@@ -1560,6 +1597,12 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end userCanDeleteSubobjects
+ public CommunityDataBackend getDataBackend() throws DataException
+ {
+ return comm.getDataBackend();
+
+ } // end getDataBackend
+
/*--------------------------------------------------------------------------------
* Implementations from interface ConferenceBackend
*--------------------------------------------------------------------------------
diff --git a/src/com/silverwrist/venice/core/impl/EngineBackend.java b/src/com/silverwrist/venice/core/impl/EngineBackend.java
index d08ba55..37724f3 100644
--- a/src/com/silverwrist/venice/core/impl/EngineBackend.java
+++ b/src/com/silverwrist/venice/core/impl/EngineBackend.java
@@ -22,15 +22,18 @@ import java.util.List;
import com.silverwrist.venice.security.AuditRecord;
import com.silverwrist.venice.htmlcheck.HTMLChecker;
import com.silverwrist.venice.core.DataException;
+import com.silverwrist.venice.core.GlobalProperties;
import com.silverwrist.venice.core.SideBoxDescriptor;
public interface EngineBackend
{
+ // HTML checker types
public static final int HTMLC_POST_BODY = 0;
public static final int HTMLC_POST_PSEUD = 1;
public static final int HTMLC_PREVIEW_BODY = 2;
public static final int HTMLC_ESCAPE_BODY_PSEUD = 3;
+ // Integer parameter indexes
public static final int IP_POSTSPERPAGE = 0;
public static final int IP_POSTSATTOP = 1;
public static final int IP_MAXSEARCHRETURN = 2;
@@ -41,6 +44,9 @@ public interface EngineBackend
public static final int IP_CREATECOMMUNITYLVL = 7;
public static final int IPC_NUM_PARAMS = 8;
+ // Boolean parameter indexes
+ public static final int BP_POSTPICTURES = 0;
+
public abstract SimpleEmailer createEmailer();
public abstract String getStockMessage(String key);
@@ -83,6 +89,8 @@ public interface EngineBackend
public abstract int getParamInt(int selector);
+ public abstract boolean getParamBoolean(int selector);
+
public abstract void forceParamReload() throws DataException;
public abstract SideBoxDescriptor getMasterSideBoxDescriptor(int id);
@@ -99,4 +107,8 @@ public interface EngineBackend
public abstract boolean isNoCompressMimeType(String type);
+ public abstract GlobalProperties getProperties();
+
+ public abstract void setProperties(GlobalProperties props) throws DataException;
+
} // end interface EngineBackend
diff --git a/src/com/silverwrist/venice/core/impl/UserContextImpl.java b/src/com/silverwrist/venice/core/impl/UserContextImpl.java
index d33fd51..3225030 100644
--- a/src/com/silverwrist/venice/core/impl/UserContextImpl.java
+++ b/src/com/silverwrist/venice/core/impl/UserContextImpl.java
@@ -21,6 +21,7 @@ import java.util.*;
import java.sql.*;
import org.apache.log4j.*;
import com.silverwrist.util.LocaleFactory;
+import com.silverwrist.util.OptionSet;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.rcache.ReferencedData;
import com.silverwrist.venice.*;
@@ -38,6 +39,14 @@ class UserContextImpl implements UserContext, UserBackend
*--------------------------------------------------------------------------------
*/
+ // Property set indexes
+ private static final int PROP_FLAGS = 0; // flags
+
+ private static final BitSet ALL_PROPS; // BitSet representing all properties
+
+ // Boolean flag indexes
+ private static final int BF_POSTPICTURES = 0;
+
private static Category logger = Category.getInstance(UserContextImpl.class);
private static final String AUTH_TOKEN_PREFIX = "VQAT:";
@@ -67,6 +76,7 @@ class UserContextImpl implements UserContext, UserBackend
private Locale my_locale = null; // my default locale (cached)
private TimeZone my_tz = null; // my default timezone (cached)
private HashMap mru_cache = new HashMap(); // MRU cache for ReferencedData objects
+ private OptionSet flags = null; // option flags
/*--------------------------------------------------------------------------------
* Constructor
@@ -147,22 +157,6 @@ class UserContextImpl implements UserContext, UserBackend
} // end loadUserData
- private void loadPrefs(Connection conn) throws SQLException, DataException
- {
- Statement stmt = conn.createStatement();
- ResultSet rs = stmt.executeQuery("SELECT * FROM userprefs WHERE uid = " + uid + ";");
-
- if (!(rs.next()))
- throw new DataException("cannot find preferences for user");
-
- if (my_tz==null)
- my_tz = TimeZone.getTimeZone(rs.getString("tzid"));
-
- if (my_locale==null)
- my_locale = LocaleFactory.createLocale(rs.getString("localeid"));
-
- } // end loadPrefs
-
private void loadPrefs() throws DataException
{
Connection conn = null;
@@ -170,7 +164,34 @@ class UserContextImpl implements UserContext, UserBackend
try
{ // call through to lower level function
conn = datapool.getConnection();
- loadPrefs(conn);
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery("SELECT * FROM userprefs WHERE uid = " + uid + ";");
+
+ if (!(rs.next()))
+ throw new DataException("cannot find preferences for user");
+
+ if (my_tz==null)
+ my_tz = TimeZone.getTimeZone(rs.getString("tzid"));
+
+ if (my_locale==null)
+ my_locale = LocaleFactory.createLocale(rs.getString("localeid"));
+
+ // Load the user properties as well.
+ rs = stmt.executeQuery("SELECT ndx, data FROM propuser WHERE uid = " + uid + ";");
+ while (rs.next())
+ { // load the properties...
+ switch (rs.getInt(1))
+ { // based on the property, do what is needed
+ case PROP_FLAGS:
+ flags = new OptionSet(rs.getString(2));
+ break;
+
+ default:
+ break;
+
+ } // end switch
+
+ } // end while
} // end try
catch (SQLException e)
@@ -282,6 +303,65 @@ class UserContextImpl implements UserContext, UserBackend
} // end autoJoinCommunities
+ private void updateProperties(BitSet delta) throws DataException
+ {
+ Connection conn = null;
+ try
+ { // get a connection and create a statement
+ conn = datapool.getConnection();
+ Statement stmt = conn.createStatement();
+ StringBuffer sql = new StringBuffer();
+
+ if (delta.get(PROP_FLAGS))
+ { // store the flags
+ sql.append("UPDATE propuser SET data = '").append(flags.asString()).append("' WHERE uid = ");
+ sql.append(uid).append(" AND ndx = ").append(PROP_FLAGS).append(';');
+ stmt.executeUpdate(sql.toString());
+ sql.setLength(0);
+
+ } // end if
+
+ } // end try
+ catch (SQLException e)
+ { // database error - this is a DataException
+ logger.error("DB error storing community properties: " + e.getMessage(),e);
+ throw new DataException("unable to save community properties: " + e.getMessage(),e);
+
+ } // end catch
+ finally
+ { // make sure the connection is released before we go
+ if (conn!=null)
+ datapool.releaseConnection(conn);
+
+ } // end finally
+
+ } // end updateProperties
+
+ private void updateProperties() throws DataException
+ {
+ updateProperties(ALL_PROPS);
+
+ } // end updateProperties
+
+ private final UserProperties createProperties()
+ {
+ UserProperties rc = new UserProperties();
+ rc.setDisplayPostPictures(flags.get(BF_POSTPICTURES));
+ return rc;
+
+ } // end createProperties
+
+ private final BitSet storeProperties(UserProperties props)
+ {
+ BitSet rc = new BitSet();
+
+ if (flags.assign(BF_POSTPICTURES,props.getDisplayPostPictures()))
+ rc.set(PROP_FLAGS);
+
+ return rc;
+
+ } // end storeProperties
+
/*--------------------------------------------------------------------------------
* Implementations from interface UserContext
*--------------------------------------------------------------------------------
@@ -1421,6 +1501,48 @@ class UserContextImpl implements UserContext, UserBackend
} // end selectAd
+ public boolean displayPostPictures() throws DataException
+ {
+ if (flags==null)
+ loadPrefs();
+
+ return flags.get(BF_POSTPICTURES);
+
+ } // end if
+
+ public UserProperties getProperties() throws DataException
+ {
+ if (flags==null)
+ loadPrefs();
+ return createProperties();
+
+ } // end getProperties
+
+ public void setProperties(UserProperties props) throws DataException
+ {
+ if (flags==null)
+ loadPrefs();
+ UserProperties orig = createProperties();
+ BitSet delta = storeProperties(props);
+ if (delta.length()==0)
+ return;
+
+ boolean succeeded = false;
+ try
+ { // update the properties in the database
+ updateProperties(delta);
+ succeeded = true;
+
+ } // end try
+ finally
+ { // make sure the connection is released before we go
+ if (!succeeded)
+ storeProperties(orig);
+
+ } // end finally
+
+ } // end setProperties
+
/*--------------------------------------------------------------------------------
* Implementations from interface UserBackend
*--------------------------------------------------------------------------------
@@ -1578,4 +1700,17 @@ class UserContextImpl implements UserContext, UserBackend
} // end autoJoinCommunities
+ /*--------------------------------------------------------------------------------
+ * Static initializer
+ *--------------------------------------------------------------------------------
+ */
+
+ static
+ { // initialize the "all properties" bit set
+ BitSet tmp = new BitSet();
+ tmp.set(PROP_FLAGS);
+ ALL_PROPS = tmp;
+
+ } // end static initializer
+
} // end class UserContextImpl
diff --git a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java
index 1eafdf2..6c639c6 100644
--- a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java
+++ b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java
@@ -22,6 +22,7 @@ import java.sql.*;
import java.util.*;
import org.apache.log4j.*;
import org.w3c.dom.*;
+import com.silverwrist.util.OptionSet;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.DOMElementHelper;
import com.silverwrist.util.rcache.*;
@@ -472,6 +473,14 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
*--------------------------------------------------------------------------------
*/
+ // Property indices
+ private static final int PROP_FLAGS = 0; // flags
+
+ private static final int _PPROP_IP_BASE = 256; // base for "pseudo property" indexes
+
+ private static final BitSet IP_PROPS; // BitSet representing the "integer parameter" properties
+ private static final BitSet ALL_PROPS; // BitSet representing all properties
+
private static Category logger = Category.getInstance(VeniceEngineImpl.class);
private static final String AUTH_ALPHABET =
@@ -506,6 +515,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
private boolean cache_fp_posts_busy = false; // busy flag for above vector
private HashSet no_compress_types = new HashSet(); // the file types that can't be compressed
private HashMap password_changes = new HashMap(); // current password change requests
+ private OptionSet global_flags = new OptionSet(); // global option flags
/*--------------------------------------------------------------------------------
* Constructor
@@ -534,10 +544,27 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
private void loadDefaults(Statement stmt) throws SQLException, DataException
{
- final String query =
+ final String query1 = "SELECT ndx, data FROM propglobal;";
+ ResultSet rs = stmt.executeQuery(query1);
+ while (rs.next())
+ { // load the property values based on indexes
+ switch (rs.getInt(1))
+ {
+ case PROP_FLAGS:
+ global_flags.assign(rs.getString(2));
+ break;
+
+ default:
+ break; // don't understand property index - ignored
+
+ } // end switch
+
+ } // end while
+
+ final String query2 =
"SELECT posts_per_page, old_posts_at_top, max_search_page, max_sig_mbr_page, max_conf_mbr_page, "
+ "fp_posts, num_audit_page, sig_create_lvl FROM globals;";
- ResultSet rs = stmt.executeQuery(query);
+ rs = stmt.executeQuery(query2);
if (!(rs.next()))
throw new DataException("Globals table does not appear to be loaded!");
@@ -553,6 +580,155 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end loadDefaults
+ private synchronized void updateDefaults(BitSet delta) throws DataException
+ {
+ Connection conn = null;
+ try
+ { // get a database connection
+ conn = datapool.getConnection();
+ Statement stmt = conn.createStatement();
+ StringBuffer sql = new StringBuffer();
+
+ if (delta.get(PROP_FLAGS))
+ { // update the global flags
+ sql.append("UPDATE propglobal SET data = '").append(global_flags.asString()).append("' WHERE ndx = ");
+ sql.append(PROP_FLAGS).append(";");
+ stmt.executeUpdate(sql.toString());
+ sql.setLength(0);
+
+ } // end if
+
+ BitSet tmp = (BitSet)(delta.clone());
+ tmp.and(IP_PROPS);
+ if (tmp.length()>0)
+ { // need to update the globals table
+ sql.append("UPDATE globals SET");
+ if (delta.get(_PPROP_IP_BASE + IP_POSTSPERPAGE))
+ sql.append(" posts_per_page = ").append(gp_ints[IP_POSTSPERPAGE]).append(',');
+ if (delta.get(_PPROP_IP_BASE + IP_POSTSATTOP))
+ sql.append(" old_posts_at_top = ").append(gp_ints[IP_POSTSATTOP]).append(',');
+ if (delta.get(_PPROP_IP_BASE + IP_MAXSEARCHRETURN))
+ sql.append(" max_search_page = ").append(gp_ints[IP_MAXSEARCHRETURN]).append(',');
+ if (delta.get(_PPROP_IP_BASE + IP_MAXCOMMUNITYMEMBERDISPLAY))
+ sql.append(" max_sig_mbr_page = ").append(gp_ints[IP_MAXCOMMUNITYMEMBERDISPLAY]).append(',');
+ if (delta.get(_PPROP_IP_BASE + IP_MAXCONFMEMBERDISPLAY))
+ sql.append(" max_conf_mbr_page = ").append(gp_ints[IP_MAXCONFMEMBERDISPLAY]).append(',');
+ if (delta.get(_PPROP_IP_BASE + IP_NUMFRONTPAGEPOSTS))
+ sql.append(" fp_posts = ").append(gp_ints[IP_NUMFRONTPAGEPOSTS]).append(',');
+ if (delta.get(_PPROP_IP_BASE + IP_NUMAUDITRECSPERPAGE))
+ sql.append(" num_audit_page = ").append(gp_ints[IP_NUMAUDITRECSPERPAGE]).append(',');
+ if (delta.get(_PPROP_IP_BASE + IP_CREATECOMMUNITYLVL))
+ sql.append(" sig_create_lvl = ").append(gp_ints[IP_CREATECOMMUNITYLVL]).append(',');
+ sql.setLength(sql.length()-1); // trim off the last comma
+ sql.append(';');
+ stmt.executeUpdate(sql.toString());
+ sql.setLength(0);
+
+ } // end if
+
+ } // end try
+ catch (SQLException e)
+ { // convert exceptions to DataException
+ logger.fatal("Database error storing defaults: " + e.getMessage(),e);
+ throw new DataException("error saving new defaults: " + e.getMessage(),e);
+
+ } // end catch
+ finally
+ { // make sure we release the connection before we go
+ if (conn!=null)
+ datapool.releaseConnection(conn);
+
+ } // end finally
+
+ } // end updateDefaults
+
+ private synchronized void updateDefaults() throws DataException
+ {
+ updateDefaults(ALL_PROPS);
+
+ } // end updateDefaults
+
+ private final GlobalProperties createProperties()
+ {
+ GlobalProperties rc = new GlobalProperties();
+ rc.setPostsPerPage(gp_ints[IP_POSTSPERPAGE]);
+ rc.setOldPostsAtTop(gp_ints[IP_POSTSATTOP]);
+ rc.setSearchItemsPerPage(gp_ints[IP_MAXSEARCHRETURN]);
+ rc.setCommunityMembersPerPage(gp_ints[IP_MAXCOMMUNITYMEMBERDISPLAY]);
+ rc.setConferenceMembersPerPage(gp_ints[IP_MAXCONFMEMBERDISPLAY]);
+ rc.setPostsOnFrontPage(gp_ints[IP_NUMFRONTPAGEPOSTS]);
+ rc.setAuditRecordsPerPage(gp_ints[IP_NUMAUDITRECSPERPAGE]);
+ rc.setCommunityCreateLevel(gp_ints[IP_CREATECOMMUNITYLVL]);
+ rc.setDisplayPostPictures(global_flags.get(BP_POSTPICTURES));
+ return rc;
+
+ } // end createProperties
+
+ private final BitSet storeProperties(GlobalProperties props)
+ {
+ BitSet rc = new BitSet();
+ if (global_flags.assign(BP_POSTPICTURES,props.getDisplayPostPictures()))
+ rc.set(PROP_FLAGS);
+ if (gp_ints[IP_POSTSPERPAGE]!=props.getPostsPerPage())
+ { // record variable change
+ gp_ints[IP_POSTSPERPAGE] = props.getPostsPerPage();
+ rc.set(_PPROP_IP_BASE + IP_POSTSPERPAGE);
+
+ } // end if
+
+ if (gp_ints[IP_POSTSATTOP]!=props.getOldPostsAtTop())
+ { // record variable change
+ gp_ints[IP_POSTSATTOP] = props.getOldPostsAtTop();
+ rc.set(_PPROP_IP_BASE + IP_POSTSATTOP);
+
+ } // end if
+
+ if (gp_ints[IP_MAXSEARCHRETURN]!=props.getSearchItemsPerPage())
+ { // record variable change
+ gp_ints[IP_MAXSEARCHRETURN] = props.getSearchItemsPerPage();
+ rc.set(_PPROP_IP_BASE + IP_MAXSEARCHRETURN);
+
+ } // end if
+
+ if (gp_ints[IP_MAXCOMMUNITYMEMBERDISPLAY]!=props.getCommunityMembersPerPage())
+ { // record variable change
+ gp_ints[IP_MAXCOMMUNITYMEMBERDISPLAY] = props.getCommunityMembersPerPage();
+ rc.set(_PPROP_IP_BASE + IP_MAXCOMMUNITYMEMBERDISPLAY);
+
+ } // end if
+
+ if (gp_ints[IP_MAXCONFMEMBERDISPLAY]!=props.getConferenceMembersPerPage())
+ { // record variable change
+ gp_ints[IP_MAXCONFMEMBERDISPLAY] = props.getConferenceMembersPerPage();
+ rc.set(_PPROP_IP_BASE + IP_MAXCONFMEMBERDISPLAY);
+
+ } // end if
+
+ if (gp_ints[IP_NUMFRONTPAGEPOSTS]!=props.getPostsOnFrontPage())
+ { // record variable change
+ gp_ints[IP_NUMFRONTPAGEPOSTS] = props.getPostsOnFrontPage();
+ rc.set(_PPROP_IP_BASE + IP_NUMFRONTPAGEPOSTS);
+
+ } // end if
+
+ if (gp_ints[IP_NUMAUDITRECSPERPAGE]!=props.getAuditRecordsPerPage())
+ { // record variable change
+ gp_ints[IP_NUMAUDITRECSPERPAGE] = props.getAuditRecordsPerPage();
+ rc.set(_PPROP_IP_BASE + IP_NUMAUDITRECSPERPAGE);
+
+ } // end if
+
+ if (gp_ints[IP_CREATECOMMUNITYLVL]!=props.getCommunityCreateLevel())
+ { // record variable change
+ gp_ints[IP_CREATECOMMUNITYLVL] = props.getCommunityCreateLevel();
+ rc.set(_PPROP_IP_BASE + IP_CREATECOMMUNITYLVL);
+
+ } // end if
+
+ return rc;
+
+ } // end storeProperties
+
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceEngine
*--------------------------------------------------------------------------------
@@ -1252,8 +1428,8 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
{ // look to see if the user name is already present
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
- stmt.executeUpdate("LOCK TABLES users WRITE, userprefs WRITE, sigmember WRITE, sideboxes WRITE, "
- + "confhotlist WRITE;");
+ stmt.executeUpdate("LOCK TABLES users WRITE, userprefs WRITE, propuser WRITE, sigmember WRITE, "
+ + "sideboxes WRITE, confhotlist WRITE;");
try
{ // make sure the user name isn't there already
ResultSet rs = stmt.executeQuery("SELECT uid FROM users WHERE username = '" + encode_username + "';");
@@ -1296,6 +1472,31 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
if (logger.isDebugEnabled())
logger.debug("...created userprefs");
+ // add a properties configuration for this user
+ rs = stmt.executeQuery("SELECT propuser.ndx, propuser.data FROM propuser, users WHERE "
+ + "propuser.uid = users.uid AND users.is_anon = 1;");
+ sql.setLength(0);
+ while (rs.next())
+ { // set up to insert into the propuser table
+ if (sql.length()==0)
+ sql.append("INSERT INTO propuser (uid, ndx, data) VALUES ");
+ else
+ sql.append(", ");
+ sql.append("(").append(new_uid).append(", ").append(rs.getInt(1)).append(", '");
+ sql.append(SQLUtil.encodeString(rs.getString(2))).append("')");
+
+ } // end while
+
+ if (sql.length()>0)
+ { // execute the big update
+ sql.append(';');
+ stmt.executeUpdate(sql.toString());
+
+ } // end if
+
+ if (logger.isDebugEnabled())
+ logger.debug("...created user properties");
+
// get the sidebox configuration for this user
rs = stmt.executeQuery("SELECT sideboxes.boxid, sideboxes.sequence FROM sideboxes, "
+ "users WHERE sideboxes.uid = users.uid AND users.is_anon = 1;");
@@ -2164,6 +2365,12 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end getParamInt
+ public boolean getParamBoolean(int selector)
+ {
+ return global_flags.get(selector);
+
+ } // end getParamBoolean
+
public void forceParamReload() throws DataException
{
Connection conn = null; // data pooled connection
@@ -2275,4 +2482,59 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end isNoCompressMimeType
+ public GlobalProperties getProperties()
+ {
+ return createProperties();
+
+ } // end getProperties
+
+ public void setProperties(GlobalProperties props) throws DataException
+ {
+ GlobalProperties orig = createProperties();
+ BitSet delta = storeProperties(props);
+ if (delta.length()==0)
+ return;
+
+ boolean succeeded = false;
+ try
+ { // write the changes out to the database
+ updateDefaults(delta);
+ succeeded = true;
+
+ } // end try
+ finally
+ { // restore old properties on failure
+ if (!succeeded)
+ storeProperties(orig);
+
+ } // end finally
+
+ } // end setProperties
+
+ /*--------------------------------------------------------------------------------
+ * Static initializer
+ *--------------------------------------------------------------------------------
+ */
+
+ static
+ { // Initialize the "integer parameter properties" BitSet.
+ BitSet tmp = new BitSet();
+ tmp.set(_PPROP_IP_BASE + IP_POSTSPERPAGE);
+ tmp.set(_PPROP_IP_BASE + IP_POSTSATTOP);
+ tmp.set(_PPROP_IP_BASE + IP_MAXSEARCHRETURN);
+ tmp.set(_PPROP_IP_BASE + IP_MAXCOMMUNITYMEMBERDISPLAY);
+ tmp.set(_PPROP_IP_BASE + IP_MAXCONFMEMBERDISPLAY);
+ tmp.set(_PPROP_IP_BASE + IP_NUMFRONTPAGEPOSTS);
+ tmp.set(_PPROP_IP_BASE + IP_NUMAUDITRECSPERPAGE);
+ tmp.set(_PPROP_IP_BASE + IP_CREATECOMMUNITYLVL);
+ IP_PROPS = tmp;
+
+ // Initialize the "all properties" BitSet.
+ tmp = new BitSet();
+ tmp.set(PROP_FLAGS);
+ tmp.or(IP_PROPS);
+ ALL_PROPS = tmp;
+
+ } // end static initializer
+
} // end class VeniceEngineImpl
diff --git a/src/com/silverwrist/venice/security/Role.java b/src/com/silverwrist/venice/security/Role.java
index 4630f7b..de5447d 100644
--- a/src/com/silverwrist/venice/security/Role.java
+++ b/src/com/silverwrist/venice/security/Role.java
@@ -52,6 +52,7 @@ public class Role implements Comparable, SecLevels
private static List confhidelist_rc = null;
private static List confdeletelist_rc = null;
private static List conf_member_levels = null;
+ private static List new_comm_list_rc = null;
/*--------------------------------------------------------------------------------
* Attributes
@@ -153,6 +154,7 @@ public class Role implements Comparable, SecLevels
rc.add(unrestricted_user);
rc.addAll(global_high);
rc.remove(rc.size()-1);
+ rc.trimToSize();
base_levels = Collections.unmodifiableList(rc);
} // end if
@@ -168,6 +170,7 @@ public class Role implements Comparable, SecLevels
ArrayList rc = new ArrayList();
rc.addAll(global_low);
rc.add(unrestricted_user);
+ rc.trimToSize();
base_levels_2 = Collections.unmodifiableList(rc);
} // end if
@@ -192,6 +195,7 @@ public class Role implements Comparable, SecLevels
rc.add(unrestricted_user);
rc.addAll(comm_high);
rc.add(global_high.get(0));
+ rc.trimToSize();
commreadlist_rc = Collections.unmodifiableList(rc);
} // end if
@@ -207,6 +211,7 @@ public class Role implements Comparable, SecLevels
ArrayList rc = new ArrayList();
rc.addAll(comm_high);
rc.addAll(global_high);
+ rc.trimToSize();
commwritelist_rc = Collections.unmodifiableList(rc);
} // end if
@@ -225,6 +230,7 @@ public class Role implements Comparable, SecLevels
rc.add(unrestricted_user);
rc.addAll(comm_high);
rc.add(global_high.get(0));
+ rc.trimToSize();
commcreatelist_rc = Collections.unmodifiableList(rc);
} // end if
@@ -241,6 +247,7 @@ public class Role implements Comparable, SecLevels
rc.addAll(comm_high);
rc.addAll(global_high);
rc.add(no_access);
+ rc.trimToSize();
commdeletelist_rc = Collections.unmodifiableList(rc);
} // end if
@@ -268,6 +275,7 @@ public class Role implements Comparable, SecLevels
rc.add(unrestricted_user);
rc.addAll(comm_high);
rc.remove(rc.size()-1);
+ rc.trimToSize();
comm_member_levels = Collections.unmodifiableList(rc);
} // end if
@@ -291,6 +299,7 @@ public class Role implements Comparable, SecLevels
rc.addAll(comm_low);
rc.addAll(conf_low);
rc.add(unrestricted_user);
+ rc.trimToSize();
confreadlist_rc = Collections.unmodifiableList(rc);
} // end if
@@ -309,6 +318,7 @@ public class Role implements Comparable, SecLevels
rc.addAll(conf_low);
rc.add(unrestricted_user);
rc.addAll(conf_high);
+ rc.trimToSize();
confpostlist_rc = Collections.unmodifiableList(rc);
} // end if
@@ -331,6 +341,7 @@ public class Role implements Comparable, SecLevels
rc.addAll(conf_high);
rc.addAll(comm_high);
rc.add(global_high.get(0));
+ rc.trimToSize();
confhidelist_rc = Collections.unmodifiableList(rc);
} // end if
@@ -359,6 +370,7 @@ public class Role implements Comparable, SecLevels
rc.addAll(comm_high);
rc.addAll(global_high);
rc.add(no_access);
+ rc.trimToSize();
confdeletelist_rc = Collections.unmodifiableList(rc);
} // end if
@@ -378,6 +390,7 @@ public class Role implements Comparable, SecLevels
rc.addAll(conf_low);
rc.add(unrestricted_user);
rc.add(conf_high.get(conf_high.size()-1));
+ rc.trimToSize();
conf_member_levels = Collections.unmodifiableList(rc);
} // end if
@@ -386,13 +399,30 @@ public class Role implements Comparable, SecLevels
} // end getConferenceMemberLevelChoices
+ public static List getNewCommunityLevelChoices()
+ {
+ if (new_comm_list_rc==null)
+ { // precalculate the list
+ ArrayList rc = new ArrayList();
+ rc.add(global_low.get(global_low.size()-1));
+ rc.add(unrestricted_user);
+ rc.addAll(global_high);
+ rc.trimToSize();
+ new_comm_list_rc = Collections.unmodifiableList(rc);
+
+ } // end if
+
+ return new_comm_list_rc;
+
+ } // end getNewCommunityLevelChoices
+
/*--------------------------------------------------------------------------------
* Static initializer
*--------------------------------------------------------------------------------
*/
static
- {
+ { // begin initializing the "all roles" map
all_roles = new HashMap();
not_in_list = new Role(0,"(not in list)");
all_roles.put(new Integer(0),not_in_list);
diff --git a/src/com/silverwrist/venice/servlets/ConfDisplay.java b/src/com/silverwrist/venice/servlets/ConfDisplay.java
index 4a107b9..a9f8d8f 100644
--- a/src/com/silverwrist/venice/servlets/ConfDisplay.java
+++ b/src/com/silverwrist/venice/servlets/ConfDisplay.java
@@ -369,8 +369,8 @@ public class ConfDisplay extends VeniceServlet
// Create the post display.
try
{ // create the display
- return new TopicPosts(request,engine,comm,conf,topic,piv.getFirst(),piv.getLast(),read_new,show_adv,
- no_bozos);
+ return new TopicPosts(request,engine,user,comm,conf,topic,piv.getFirst(),piv.getLast(),read_new,
+ show_adv,no_bozos);
} // end try
catch (DataException de)
@@ -430,7 +430,8 @@ public class ConfDisplay extends VeniceServlet
PostInterval piv = getInterval(engine,request,topic,on_error);
// create the topic posts view
- return new TopicPosts(request,engine,comm,conf,topic,piv.getFirst(),piv.getLast(),true,false,false);
+ return new TopicPosts(request,engine,user,comm,conf,topic,piv.getFirst(),piv.getLast(),true,
+ false,false);
} // end try
catch (DataException de)
diff --git a/src/com/silverwrist/venice/servlets/SystemAdmin.java b/src/com/silverwrist/venice/servlets/SystemAdmin.java
index 235edfa..71fa9fb 100644
--- a/src/com/silverwrist/venice/servlets/SystemAdmin.java
+++ b/src/com/silverwrist/venice/servlets/SystemAdmin.java
@@ -75,6 +75,23 @@ public class SystemAdmin extends VeniceServlet
} // end makeAdminModifyUserDialog
+ private EditGlobalPropertiesDialog makeGlobalPropertiesDialog() throws ServletException
+ {
+ final String desired_name = "EditGlobalPropertiesDialog";
+ DialogCache cache = DialogCache.getDialogCache(getServletContext());
+
+ if (!(cache.isCached(desired_name)))
+ { // create a template and save it off
+ EditGlobalPropertiesDialog template = new EditGlobalPropertiesDialog();
+ cache.saveTemplate(template);
+
+ } // end if
+
+ // return a new copy
+ return (EditGlobalPropertiesDialog)(cache.getNewDialog(desired_name));
+
+ } // end makeGlobalPropertiesDialog
+
/*--------------------------------------------------------------------------------
* Overrides from class HttpServlet
*--------------------------------------------------------------------------------
@@ -193,6 +210,25 @@ public class SystemAdmin extends VeniceServlet
} // end if ("UM" command)
+ if (cmd.equals("G"))
+ { // "G" = Edit Global Properties
+ try
+ { // get the global properties
+ AdminOperations adm = user.getAdminInterface();
+ EditGlobalPropertiesDialog dlg = makeGlobalPropertiesDialog();
+ dlg.setupDialog(adm);
+ setMyLocation(request,"sysadmin?cmd=G");
+ return dlg;
+
+ } // end try
+ catch (AccessError ae)
+ { // an access error generally means we're not an administrator
+ return new ErrorBox("Access Error","You do not have permission to administer the system.",null);
+
+ } // end catch
+
+ } // end if
+
// TODO: other command handling
if (!(user.hasAdminAccess()))
@@ -274,7 +310,7 @@ public class SystemAdmin extends VeniceServlet
} // end if
else
{ // the button must be wrong!
- logger.error("no known button click on Account.doPost, cmd=P");
+ logger.error("no known button click on SystemAdmin.doPost, cmd=UF");
return new ErrorBox("Internal Error","Unknown command button pressed","sysadmin?cmd=UF");
} // end else
@@ -299,6 +335,57 @@ public class SystemAdmin extends VeniceServlet
} // end if ("UM" command)
+ if (cmd.equals("G"))
+ { // "G" - Edit Global Properties
+ try
+ { // get the dialog box
+ EditGlobalPropertiesDialog dlg = makeGlobalPropertiesDialog();
+
+ if (dlg.isButtonClicked(request,"cancel"))
+ throw new RedirectResult("sysadmin"); // we decided not to bother - go back
+
+ if (dlg.isButtonClicked(request,"update"))
+ { // update the system properties
+ AdminOperations adm = user.getAdminInterface();
+ dlg.loadValues(request);
+
+ try
+ { // execute the dialog!
+ dlg.doDialog(adm);
+ throw new RedirectResult("sysadmin");
+
+ } // end try
+ catch (ValidationException ve)
+ { // validation error - retry the dialog
+ dlg.setErrorMessage(ve.getMessage() + " Please try again.");
+ setMyLocation(request,"sysadmin?cmd=G");
+ return dlg;
+
+ } // end catch
+
+ } // end if
+ else
+ { // the button must be wrong!
+ logger.error("no known button click on SystemAdmin.doPost, cmd=G");
+ return new ErrorBox("Internal Error","Unknown command button pressed","sysadmin?cmd=UF");
+
+ } // end else
+
+ } // end try
+ catch (AccessError ae)
+ { // an access error generally means we're not an administrator
+ return new ErrorBox("Access Error","You do not have permission to administer the system.",null);
+
+ } // end catch
+ catch (DataException de)
+ { // error pulling the audit records
+ return new ErrorBox("Database Error","Unable to update global properties: " + de.getMessage(),
+ "sysadmin");
+
+ } // end catch
+
+ } // end if ("G" command)
+
// TODO: other command handling
if (!(user.hasAdminAccess()))
diff --git a/src/com/silverwrist/venice/servlets/format/CDBaseFormField.java b/src/com/silverwrist/venice/servlets/format/CDBaseFormField.java
index 7e3e238..c51061f 100644
--- a/src/com/silverwrist/venice/servlets/format/CDBaseFormField.java
+++ b/src/com/silverwrist/venice/servlets/format/CDBaseFormField.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
@@ -24,6 +24,11 @@ import com.silverwrist.venice.ValidationException;
public abstract class CDBaseFormField implements CDFormField, ColorSelectors
{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
private String name;
private String caption;
private String caption2;
@@ -31,6 +36,11 @@ public abstract class CDBaseFormField implements CDFormField, ColorSelectors
private String value = null;
private boolean enabled;
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
protected CDBaseFormField(String name, String caption, String caption2, boolean required)
{
this.name = name;
@@ -52,12 +62,10 @@ public abstract class CDBaseFormField implements CDFormField, ColorSelectors
} // end constructor
- protected abstract void renderActualField(Writer out, RenderData rdat)
- throws IOException;
-
- protected void validateContents(String value) throws ValidationException
- { // this is a do-nothing value
- } // end validateContents
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
protected final String getCaption()
{
@@ -65,6 +73,28 @@ public abstract class CDBaseFormField implements CDFormField, ColorSelectors
} // end getCaption
+ /*--------------------------------------------------------------------------------
+ * Abstract functions which MUST be overriden
+ *--------------------------------------------------------------------------------
+ */
+
+ protected abstract void renderActualField(Writer out, RenderData rdat)
+ throws IOException;
+
+ /*--------------------------------------------------------------------------------
+ * Overridable operations
+ *--------------------------------------------------------------------------------
+ */
+
+ protected void validateContents(String value) throws ValidationException
+ { // this is a do-nothing value
+ } // end validateContents
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentRender
+ *--------------------------------------------------------------------------------
+ */
+
public void renderHere(Writer out, RenderData rdat) throws IOException
{
out.write("
\n
\n
");
@@ -81,6 +111,11 @@ public abstract class CDBaseFormFieldReverse implements CDFormField, ColorSelect
} // end renderHere
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface CDFormField
+ *--------------------------------------------------------------------------------
+ */
+
public String getName()
{
return name;
@@ -99,6 +134,18 @@ public abstract class CDBaseFormFieldReverse implements CDFormField, ColorSelect
} // end setValue
+ public Object getObjValue()
+ {
+ return value;
+
+ } // end getObjValue
+
+ public void setObjValue(Object obj)
+ {
+ this.value = obj.toString();
+
+ } // end setObjValue
+
public boolean isRequired()
{
return required;
diff --git a/src/com/silverwrist/venice/servlets/format/CDCheckBoxFormField.java b/src/com/silverwrist/venice/servlets/format/CDCheckBoxFormField.java
index 310f8e6..d675168 100644
--- a/src/com/silverwrist/venice/servlets/format/CDCheckBoxFormField.java
+++ b/src/com/silverwrist/venice/servlets/format/CDCheckBoxFormField.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
@@ -24,8 +24,25 @@ import com.silverwrist.venice.ValidationException;
public class CDCheckBoxFormField extends CDBaseFormFieldReverse
{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String YES = "Y";
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
private String on_value;
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
public CDCheckBoxFormField(String name, String caption, String caption2, String on_value)
{
super(name,caption,caption2,false);
@@ -33,6 +50,13 @@ public class CDCheckBoxFormField extends CDBaseFormFieldReverse
} // end constructor
+ public CDCheckBoxFormField(String name, String caption, String caption2)
+ {
+ super(name,caption,caption2,false);
+ this.on_value = YES;
+
+ } // end constructor
+
protected CDCheckBoxFormField(CDCheckBoxFormField other)
{
super(other);
@@ -40,6 +64,11 @@ public class CDCheckBoxFormField extends CDBaseFormFieldReverse
} // end constructor
+ /*--------------------------------------------------------------------------------
+ * Overrides from class CDBaseFormFieldReverse
+ *--------------------------------------------------------------------------------
+ */
+
protected void renderActualField(Writer out, RenderData rdat) throws IOException
{
out.write(",
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
@@ -25,10 +25,20 @@ import com.silverwrist.venice.ValidationException;
public class CDFormCategoryHeader implements CDFormField, ColorSelectors
{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
private String caption;
private String rtext;
private boolean enabled;
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
public CDFormCategoryHeader(String caption)
{
this.caption = caption;
@@ -53,6 +63,11 @@ public class CDFormCategoryHeader implements CDFormField, ColorSelectors
} // end constructor
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface ComponentRender
+ *--------------------------------------------------------------------------------
+ */
+
public void renderHere(Writer out, RenderData rdat) throws IOException
{
out.write("
,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
@@ -27,6 +27,10 @@ public interface CDFormField extends ComponentRender
public abstract void setValue(String value);
+ public abstract Object getObjValue();
+
+ public abstract void setObjValue(Object obj);
+
public abstract boolean isRequired();
public abstract void validate() throws ValidationException;
diff --git a/src/com/silverwrist/venice/servlets/format/CDIntegerFormField.java b/src/com/silverwrist/venice/servlets/format/CDIntegerFormField.java
new file mode 100644
index 0000000..5e54ad3
--- /dev/null
+++ b/src/com/silverwrist/venice/servlets/format/CDIntegerFormField.java
@@ -0,0 +1,142 @@
+/*
+ * 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.venice.ValidationException;
+
+public class CDIntegerFormField extends CDTextFormField
+{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final double LN10 = Math.log(10.0);
+
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private int min_value;
+ private int max_value;
+
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public CDIntegerFormField(String name, String caption, String caption2, int min, int max)
+ {
+ super(name,caption,caption2,true,numDigits(min,max),numDigits(min,max));
+ this.min_value = min;
+ this.max_value = max;
+
+ } // end constructor
+
+ protected CDIntegerFormField(CDIntegerFormField other)
+ {
+ super(other);
+ this.min_value = other.min_value;
+ this.max_value = other.max_value;
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private static int numDigits(int v)
+ {
+ if (v==0)
+ return 1;
+ else if (v>0)
+ return 1 + (int)(Math.floor(Math.log((double)v) / LN10));
+ else
+ return 2 + (int)(Math.floor(Math.log((double)(-v)) / LN10));
+
+ } // end numDigits
+
+ private static int numDigits(int min, int max)
+ {
+ return Math.max(Math.max(numDigits(min),numDigits(max)),2);
+
+ } // end numDigits
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class CDTextFormField
+ *--------------------------------------------------------------------------------
+ */
+
+ protected void renderActualField(Writer out, RenderData rdat) throws IOException
+ {
+ super.renderActualField(out,rdat);
+ out.write(" (" + min_value + " - " + max_value + ")");
+
+ } // end renderActualField
+
+ protected void validateContents(String value) throws ValidationException
+ {
+ try
+ { // convert to an integer and check against range
+ int x = Integer.parseInt(value);
+ if ((min_value>Integer.MIN_VALUE) && (xmax_value))
+ throw new ValidationException("The value of the '" + getCaption()
+ + "' field must be less than or equal to " + max_value + ".");
+
+ } // end try
+ catch (NumberFormatException nfe)
+ { // integer conversion failed
+ throw new ValidationException("Invalid non-numeric character in the '" + getCaption() + "' field.");
+
+ } // end catch
+
+ } // end validateContents
+
+ /*--------------------------------------------------------------------------------
+ * Implementations from interface CDFormField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object getObjValue()
+ {
+ try
+ { // build an Integer and return it
+ return new Integer(getValue());
+
+ } // end try
+ catch (NumberFormatException nfe)
+ { // shouldn't happen
+ return null;
+
+ } // end catch
+
+ } // end getObjValue
+
+ public CDFormField duplicate()
+ {
+ return new CDIntegerFormField(this);
+
+ } // end clone
+
+} // end class CDIntegerFormField
diff --git a/src/com/silverwrist/venice/servlets/format/CDRoleListFormField.java b/src/com/silverwrist/venice/servlets/format/CDRoleListFormField.java
index 9e4f0c8..bb18404 100644
--- a/src/com/silverwrist/venice/servlets/format/CDRoleListFormField.java
+++ b/src/com/silverwrist/venice/servlets/format/CDRoleListFormField.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
@@ -25,6 +25,11 @@ import com.silverwrist.venice.security.Role;
public class CDRoleListFormField extends CDPickListFormField
{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
public CDRoleListFormField(String name, String caption, String caption2, boolean required,
List role_list)
{
@@ -38,6 +43,11 @@ public class CDRoleListFormField extends CDPickListFormField
} // end constructor
+ /*--------------------------------------------------------------------------------
+ * Overrides from class CDPickListFormField
+ *--------------------------------------------------------------------------------
+ */
+
protected void renderChoice(Writer out, RenderData rdat, Object obj, String my_value) throws IOException
{
Role r = (Role)obj;
@@ -48,6 +58,26 @@ public class CDRoleListFormField extends CDPickListFormField
} // end renderChoice
+ /*--------------------------------------------------------------------------------
+ * Implementations from class CDFormField
+ *--------------------------------------------------------------------------------
+ */
+
+ public Object getObjValue()
+ {
+ try
+ { // return value as Integer, for now
+ return new Integer(super.getValue());
+
+ } // end try
+ catch (NumberFormatException nfe)
+ {
+ return null;
+
+ } // end catch
+
+ } // end getObjValue
+
public CDFormField duplicate()
{
return new CDRoleListFormField(this);
@@ -55,3 +85,4 @@ public class CDRoleListFormField extends CDPickListFormField
} // end clone
} // end class CDRoleListFormField
+
diff --git a/src/com/silverwrist/venice/servlets/format/CDTextFormField.java b/src/com/silverwrist/venice/servlets/format/CDTextFormField.java
index 55305c8..04dddcd 100644
--- a/src/com/silverwrist/venice/servlets/format/CDTextFormField.java
+++ b/src/com/silverwrist/venice/servlets/format/CDTextFormField.java
@@ -23,9 +23,19 @@ import com.silverwrist.venice.ValidationException;
public class CDTextFormField extends CDBaseFormField
{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
private int size;
private int maxlength;
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
public CDTextFormField(String name, String caption, String caption2, boolean required,
int size, int maxlength)
{
@@ -43,6 +53,11 @@ public class CDTextFormField extends CDBaseFormField
} // end constructor
+ /*--------------------------------------------------------------------------------
+ * Overrides from class CDBaseFormField
+ *--------------------------------------------------------------------------------
+ */
+
protected void renderActualField(Writer out, RenderData rdat) throws IOException
{
out.write(".
+ *
+ * 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 java.util.*;
+import com.silverwrist.util.StringUtil;
+import com.silverwrist.venice.ValidationException;
+import com.silverwrist.venice.security.Role;
+import com.silverwrist.venice.core.*;
+
+public class EditGlobalPropertiesDialog extends ContentDialog
+{
+ /*--------------------------------------------------------------------------------
+ * Constructors
+ *--------------------------------------------------------------------------------
+ */
+
+ public EditGlobalPropertiesDialog()
+ {
+ super("Edit Global Properties",null,"globpropform","sysadmin");
+ setHiddenField("cmd","G");
+
+ addFormField(new CDFormCategoryHeader("System Properties"));
+ addFormField(new CDIntegerFormField("search_items","Number of search items to display per page",
+ null,5,100));
+ addFormField(new CDIntegerFormField("fp_posts","Number of published posts to display on front page",
+ null,1,50));
+ addFormField(new CDIntegerFormField("audit_recs","Number of audit records to display per page",
+ null,10,500));
+ addFormField(new CDRoleListFormField("create_lvl","Security level required to create a new community",
+ null,true,Role.getNewCommunityLevelChoices()));
+
+ addFormField(new CDFormCategoryHeader("Community Properties"));
+ addFormField(new CDIntegerFormField("comm_mbrs","Number of community members to display per page",
+ null,10,100));
+
+ addFormField(new CDFormCategoryHeader("Conferencing Properties"));
+ addFormField(new CDIntegerFormField("posts_page","Maximum number of posts to display per page",
+ null,5,100));
+ addFormField(new CDIntegerFormField("old_posts","Number of \"old\" posts to display at top of page",
+ null,1,5));
+ addFormField(new CDIntegerFormField("conf_mbrs","Number of conference members to display per page",
+ null,10,100));
+ addFormField(new CDCheckBoxFormField("pic_in_post","Display user pictures next to posts in conferences",
+ "(by default; user can override)"));
+
+ addCommandButton(new CDImageButton("update","bn_update.gif","Update",80,24));
+ addCommandButton(new CDImageButton("cancel","bn_cancel.gif","Cancel",80,24));
+
+ } // end constructor
+
+ protected EditGlobalPropertiesDialog(EditGlobalPropertiesDialog other)
+ {
+ super(other);
+
+ } // end constructor
+
+ /*--------------------------------------------------------------------------------
+ * External operations
+ *--------------------------------------------------------------------------------
+ */
+
+ public void setupDialog(AdminOperations adm)
+ {
+ GlobalProperties props = adm.getProperties();
+ setFieldObjValue("search_items",new Integer(props.getSearchItemsPerPage()));
+ setFieldObjValue("fp_posts",new Integer(props.getPostsOnFrontPage()));
+ setFieldObjValue("audit_recs",new Integer(props.getAuditRecordsPerPage()));
+ setFieldObjValue("create_lvl",new Integer(props.getCommunityCreateLevel()));
+ setFieldObjValue("comm_mbrs",new Integer(props.getCommunityMembersPerPage()));
+ setFieldObjValue("posts_page",new Integer(props.getPostsPerPage()));
+ setFieldObjValue("old_posts",new Integer(props.getOldPostsAtTop()));
+ setFieldObjValue("conf_mbrs",new Integer(props.getConferenceMembersPerPage()));
+ setFieldObjValue("pic_in_post",new Boolean(props.getDisplayPostPictures()));
+
+ } // end setupDialog
+
+ public void doDialog(AdminOperations adm) throws ValidationException, DataException
+ {
+ validate(); // validate the dialog
+
+ // Reset the global properties.
+ GlobalProperties props = adm.getProperties();
+ Integer iv = (Integer)(getFieldObjValue("search_items"));
+ props.setSearchItemsPerPage(iv.intValue());
+ iv = (Integer)(getFieldObjValue("fp_posts"));
+ props.setPostsOnFrontPage(iv.intValue());
+ iv = (Integer)(getFieldObjValue("audit_recs"));
+ props.setAuditRecordsPerPage(iv.intValue());
+ iv = (Integer)(getFieldObjValue("create_lvl"));
+ props.setCommunityCreateLevel(iv.intValue());
+ iv = (Integer)(getFieldObjValue("comm_mbrs"));
+ props.setCommunityMembersPerPage(iv.intValue());
+ iv = (Integer)(getFieldObjValue("posts_page"));
+ props.setPostsPerPage(iv.intValue());
+ iv = (Integer)(getFieldObjValue("old_posts"));
+ props.setOldPostsAtTop(iv.intValue());
+ iv = (Integer)(getFieldObjValue("conf_mbrs"));
+ props.setConferenceMembersPerPage(iv.intValue());
+ Boolean bv = (Boolean)(getFieldObjValue("pic_in_post"));
+ props.setDisplayPostPictures(bv.booleanValue());
+ adm.setProperties(props);
+
+ } // end doDialog
+
+ public Object clone()
+ {
+ return new EditGlobalPropertiesDialog(this);
+
+ } // end clone
+
+} // end class EditGlobalPropertiesDialog
diff --git a/src/com/silverwrist/venice/servlets/format/EditProfileDialog.java b/src/com/silverwrist/venice/servlets/format/EditProfileDialog.java
index 60d2563..ed18ec9 100644
--- a/src/com/silverwrist/venice/servlets/format/EditProfileDialog.java
+++ b/src/com/silverwrist/venice/servlets/format/EditProfileDialog.java
@@ -81,6 +81,13 @@ public class EditProfileDialog extends ContentDialog
} // end class CDUserPhotoControl
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static final String YES = "Y";
+
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
@@ -113,7 +120,7 @@ public class EditProfileDialog extends ContentDialog
addFormField(new CDTextFormField("company","Company",null,false,32,255));
addFormField(new CDTextFormField("addr1","Address",null,false,32,255));
addFormField(new CDTextFormField("addr2","Address","(line 2)",false,32,255));
- addFormField(new CDCheckBoxFormField("pvt_addr","Hide address in profile",null,"Y"));
+ addFormField(new CDCheckBoxFormField("pvt_addr","Hide address in profile",null,YES));
addFormField(new CDTextFormField("loc","City",null,true,32,64));
addFormField(new CDTextFormField("reg","State/Province",null,true,32,64));
addFormField(new CDTextFormField("pcode","Zip/Postal Code",null,true,32,64));
@@ -121,18 +128,20 @@ public class EditProfileDialog extends ContentDialog
addFormField(new CDFormCategoryHeader("Phone Numbers"));
addFormField(new CDTextFormField("phone","Telephone",null,false,32,32));
addFormField(new CDTextFormField("mobile","Mobile/cellphone",null,false,32,32));
- addFormField(new CDCheckBoxFormField("pvt_phone","Hide phone/mobile numbers in profile",null,"Y"));
+ addFormField(new CDCheckBoxFormField("pvt_phone","Hide phone/mobile numbers in profile",null,YES));
addFormField(new CDTextFormField("fax","Fax",null,false,32,32));
- addFormField(new CDCheckBoxFormField("pvt_fax","Hide fax number in profile",null,"Y"));
+ addFormField(new CDCheckBoxFormField("pvt_fax","Hide fax number in profile",null,YES));
addFormField(new CDFormCategoryHeader("Internet"));
addFormField(new CDEmailAddressFormField("email","E-mail address",null,true,32,255));
- addFormField(new CDCheckBoxFormField("pvt_email","Hide e-mail address in profile",null,"Y"));
+ addFormField(new CDCheckBoxFormField("pvt_email","Hide e-mail address in profile",null,YES));
addFormField(new CDTextFormField("url","Home page","(URL)",false,32,255));
addFormField(new CDFormCategoryHeader("Personal"));
addFormField(new CDTextFormField("descr","Personal description",null,false,32,255));
photo_control = new CDUserPhotoControl("photo","User Photo","userphoto");
addFormField(photo_control);
addFormField(new CDFormCategoryHeader("User Preferences"));
+ addFormField(new CDCheckBoxFormField("pic_in_post","Display user photos next to conference posts",
+ "(where applicable)",YES));
addFormField(new CDLocaleListFormField("locale","Default locale","(for formatting dates/times)",true));
addFormField(new CDTimeZoneListFormField("tz","Default time zone",null,true));
addCommandButton(new CDImageButton("update","bn_update.gif","Update",80,24));
@@ -198,6 +207,7 @@ public class EditProfileDialog extends ContentDialog
{
setTarget(target);
ContactInfo ci = uc.getContactInfo(); // get the main contact info
+ UserProperties props = uc.getProperties(); // get the properties
setFieldValue("prefix",ci.getNamePrefix());
setFieldValue("first",ci.getGivenName());
@@ -210,7 +220,7 @@ public class EditProfileDialog extends ContentDialog
setFieldValue("addr1",ci.getAddressLine1());
setFieldValue("addr2",ci.getAddressLine2());
if (ci.getPrivateAddress())
- setFieldValue("pvt_addr","Y");
+ setFieldValue("pvt_addr",YES);
setFieldValue("loc",ci.getLocality());
setFieldValue("reg",ci.getRegion());
setFieldValue("pcode",ci.getPostalCode());
@@ -218,17 +228,19 @@ public class EditProfileDialog extends ContentDialog
setFieldValue("phone",ci.getPhone());
setFieldValue("mobile",ci.getMobile());
if (ci.getPrivatePhone())
- setFieldValue("pvt_phone","Y");
+ setFieldValue("pvt_phone",YES);
setFieldValue("fax",ci.getFax());
if (ci.getPrivateFax())
- setFieldValue("pvt_fax","Y");
+ setFieldValue("pvt_fax",YES);
setFieldValue("email",ci.getEmail());
if (ci.getPrivateEmail())
- setFieldValue("pvt_email","Y");
+ setFieldValue("pvt_email",YES);
setFieldValue("url",ci.getURL());
setFieldValue("descr",uc.getDescription());
setFieldValue("photo",ci.getPhotoURL());
photo_control.setLinkURL("userphoto?tgt=" + URLEncoder.encode(target));
+ if (props.getDisplayPostPictures())
+ setFieldValue("pic_in_post",YES);
setFieldValue("locale",uc.getLocale().toString());
setFieldValue("tz",uc.getTimeZone().getID());
@@ -238,8 +250,8 @@ public class EditProfileDialog extends ContentDialog
{
validate(); // validate the dialog
- final String yes = "Y"; // the "yes" string
ContactInfo ci = uc.getContactInfo(); // get the main contact info
+ UserProperties props = uc.getProperties();
// Reset all the contact info fields.
ci.setNamePrefix(getFieldValue("prefix"));
@@ -254,23 +266,27 @@ public class EditProfileDialog extends ContentDialog
ci.setCompany(getFieldValue("company"));
ci.setAddressLine1(getFieldValue("addr1"));
ci.setAddressLine2(getFieldValue("addr2"));
- ci.setPrivateAddress(yes.equals(getFieldValue("pvt_addr")));
+ ci.setPrivateAddress(YES.equals(getFieldValue("pvt_addr")));
ci.setLocality(getFieldValue("loc"));
ci.setRegion(getFieldValue("reg"));
ci.setPostalCode(getFieldValue("pcode"));
ci.setCountry(getFieldValue("country"));
ci.setPhone(getFieldValue("phone"));
ci.setMobile(getFieldValue("mobile"));
- ci.setPrivatePhone(yes.equals(getFieldValue("pvt_phone")));
+ ci.setPrivatePhone(YES.equals(getFieldValue("pvt_phone")));
ci.setFax(getFieldValue("fax"));
- ci.setPrivateFax(yes.equals(getFieldValue("pvt_fax")));
+ ci.setPrivateFax(YES.equals(getFieldValue("pvt_fax")));
ci.setEmail(getFieldValue("email"));
- ci.setPrivateEmail(yes.equals(getFieldValue("pvt_email")));
+ ci.setPrivateEmail(YES.equals(getFieldValue("pvt_email")));
ci.setURL(getFieldValue("url"));
// Store the completed contact info.
boolean retval = uc.putContactInfo(ci);
+ // Save off the properties.
+ props.setDisplayPostPictures(YES.equals(getFieldValue("pic_in_post")));
+ uc.setProperties(props);
+
// Save off the user's description and preferences.
uc.setDescription(getFieldValue("descr"));
uc.setLocale(LocaleFactory.createLocale(getFieldValue("locale")));
diff --git a/src/com/silverwrist/venice/servlets/format/SystemAdminTop.java b/src/com/silverwrist/venice/servlets/format/SystemAdminTop.java
index ac0f577..b09fe3c 100644
--- a/src/com/silverwrist/venice/servlets/format/SystemAdminTop.java
+++ b/src/com/silverwrist/venice/servlets/format/SystemAdminTop.java
@@ -31,7 +31,7 @@ public class SystemAdminTop extends ContentMenuPanel
public SystemAdminTop()
{
super("System Administration",null);
- addChoice("Set Global Parameters","TODO");
+ addChoice("Edit Global Properties","sysadmin?cmd=G");
addChoice("View/Edit Banned Users","TODO");
addChoice("User Account Management","sysadmin?cmd=UF");
addChoice("System Audit Logs","sysadmin?cmd=A");
diff --git a/src/com/silverwrist/venice/servlets/format/TopicPosts.java b/src/com/silverwrist/venice/servlets/format/TopicPosts.java
index f484c06..5d2f9c6 100644
--- a/src/com/silverwrist/venice/servlets/format/TopicPosts.java
+++ b/src/com/silverwrist/venice/servlets/format/TopicPosts.java
@@ -17,6 +17,7 @@
*/
package com.silverwrist.venice.servlets.format;
+import java.awt.Dimension;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
@@ -56,13 +57,15 @@ public class TopicPosts implements JSPRender
private String topic_qid;
private String cache_locator = null;
private HashSet bozo_uids = new HashSet();
+ private Dimension photo_size = null;
+ private HashMap uid_photos = null;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
- public TopicPosts(HttpServletRequest request, VeniceEngine engine, CommunityContext comm,
+ public TopicPosts(HttpServletRequest request, VeniceEngine engine, UserContext user, CommunityContext comm,
ConferenceContext conf, TopicContext topic, int first, int last, boolean read_new,
boolean show_advanced, boolean no_bozos) throws DataException, AccessError
{
@@ -93,16 +96,38 @@ public class TopicPosts implements JSPRender
// build up the list of users IN THIS VIEW that are bozo-filtered
HashSet saw_users = new HashSet();
+ if (conf.displayPostPictures() && user.displayPostPictures())
+ { // build up the mapping of UIDs to photo URLs
+ photo_size = engine.getUserPhotoSize();
+ uid_photos = new HashMap();
+
+ } // end if
+
Iterator it = messages.iterator();
while (it.hasNext())
{ // get the user IDs of all messages on this page
TopicMessageContext msg = (TopicMessageContext)(it.next());
Integer the_uid = new Integer(msg.getCreatorUID());
+ boolean get_photo;
if (!(saw_users.contains(the_uid)))
{ // only check user IDs once per display operation
saw_users.add(the_uid);
+ get_photo = true;
if (topic.isBozo(the_uid.intValue()))
+ { // shall we get the user photo?
bozo_uids.add(the_uid);
+ get_photo = no_bozos;
+
+ } // end if
+
+ if (conf.displayPostPictures() && user.displayPostPictures() && get_photo)
+ { // look up the user photo URL
+ UserProfile prof = user.getProfile(the_uid.intValue());
+ String url = prof.getPhotoURL();
+ if (url!=null)
+ uid_photos.put(the_uid,url);
+
+ } // end else if
} // end if
@@ -470,4 +495,24 @@ public class TopicPosts implements JSPRender
} // end showFilterButton
+ public String getUserPhotoTag(int uid, RenderData rdat)
+ {
+ if (photo_size==null)
+ return ""; // user photos not enabled
+ StringBuffer buf = new StringBuffer("");
+ return buf.toString();
+
+ } // end getUserPhotoTag
+
+ public boolean displayPostPictures()
+ {
+ return (photo_size!=null);
+
+ } // end displayPostPictures
+
} // end class TopicPosts
diff --git a/web/format/posts.jsp b/web/format/posts.jsp
index 21c7bb3..b76719b 100644
--- a/web/format/posts.jsp
+++ b/web/format/posts.jsp
@@ -166,6 +166,9 @@
<% } // end if (showing advanced controls) %>
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
+ <% if (!(data.bozoFilterUser(msg.getCreatorUID()))) { %>
+ <%= data.getUserPhotoTag(msg.getCreatorUID(),rdat) %>
+ <% } // end if %>
"><%= msg.getPostNumber() %> of
<%= data.getTotalMessages() - 1 %>
@@ -200,7 +203,8 @@
(Scribbled by <%= data.getMessageBodyText(msg) %> on
<%= rdat.formatDateForDisplay(msg.getScribbleDate()) %>)
-
+
+ <% if (data.displayPostPictures()) { %> <% } %>