From 070fd2c9e2c2fe6b48867b85eeee6313c953494b Mon Sep 17 00:00:00 2001 From: "Eric J. Bowersox" Date: Sun, 11 Nov 2001 01:22:07 +0000 Subject: [PATCH] implemented the "pics in posts" flag globally...it marks the first appearance of "properties" storage and editing for conferences, communities, users, and the global system. In addition, the "global properties" editing screen got implemented, because it wasn't there yet. --- setup/database.sql | 48 ++++ src/com/silverwrist/util/OptionSet.java | 16 +- .../venice/core/AdminOperations.java | 4 + .../venice/core/CommunityContext.java | 4 + .../venice/core/CommunityProperties.java | 57 ++++ .../venice/core/ConferenceContext.java | 6 + .../venice/core/ConferenceProperties.java | 57 ++++ .../venice/core/GlobalProperties.java | 169 +++++++++++ .../silverwrist/venice/core/UserContext.java | 6 + .../venice/core/UserProperties.java | 57 ++++ .../venice/core/impl/AdminOperationsImpl.java | 12 + .../core/impl/BackgroundCommunityPurge.java | 2 + .../core/impl/BackgroundConferencePurge.java | 2 +- .../venice/core/impl/CommunityBackend.java | 2 + .../venice/core/impl/CommunityCoreData.java | 170 ++++++++++- .../venice/core/impl/CommunityData.java | 5 + .../core/impl/CommunityDataBackend.java | 5 + .../core/impl/CommunityUserContextImpl.java | 36 +++ .../core/impl/ConferenceCommunityContext.java | 7 + .../impl/ConferenceCommunityContextImpl.java | 22 ++ .../venice/core/impl/ConferenceCoreData.java | 180 +++++++++++- .../venice/core/impl/ConferenceData.java | 7 + .../core/impl/ConferenceUserContextImpl.java | 43 +++ .../venice/core/impl/EngineBackend.java | 12 + .../venice/core/impl/UserContextImpl.java | 169 +++++++++-- .../venice/core/impl/VeniceEngineImpl.java | 270 +++++++++++++++++- src/com/silverwrist/venice/security/Role.java | 32 ++- .../venice/servlets/ConfDisplay.java | 7 +- .../venice/servlets/SystemAdmin.java | 89 +++++- .../servlets/format/CDBaseFormField.java | 61 +++- .../format/CDBaseFormFieldReverse.java | 59 +++- .../servlets/format/CDCheckBoxFormField.java | 51 +++- .../servlets/format/CDFormCategoryHeader.java | 32 ++- .../venice/servlets/format/CDFormField.java | 6 +- .../servlets/format/CDIntegerFormField.java | 142 +++++++++ .../servlets/format/CDRoleListFormField.java | 33 ++- .../servlets/format/CDTextFormField.java | 20 ++ .../servlets/format/CDVeniceIDFormField.java | 12 +- .../venice/servlets/format/ContentDialog.java | 24 ++ .../format/EditCommunityProfileDialog.java | 30 +- .../servlets/format/EditConferenceDialog.java | 27 +- .../format/EditGlobalPropertiesDialog.java | 128 +++++++++ .../servlets/format/EditProfileDialog.java | 42 ++- .../servlets/format/SystemAdminTop.java | 2 +- .../venice/servlets/format/TopicPosts.java | 47 ++- web/format/posts.jsp | 10 +- 46 files changed, 2135 insertions(+), 87 deletions(-) create mode 100644 src/com/silverwrist/venice/core/CommunityProperties.java create mode 100644 src/com/silverwrist/venice/core/ConferenceProperties.java create mode 100644 src/com/silverwrist/venice/core/GlobalProperties.java create mode 100644 src/com/silverwrist/venice/core/UserProperties.java create mode 100644 src/com/silverwrist/venice/servlets/format/CDIntegerFormField.java create mode 100644 src/com/silverwrist/venice/servlets/format/EditGlobalPropertiesDialog.java 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()) { %>
<% } %>

<% } else if (data.bozoFilterUser(msg.getCreatorUID())) { %> ">(Hidden Message: <%= msg.getNumLines() %> <% if (msg.getNumLines()==1) { %>Line<% } else { %>Lines<% } %>) -

+ + <% if (data.displayPostPictures()) { %>
<% } %>

<% } else { %>

<%= rdat.rewritePostData(data.getMessageBodyText(msg)) %>
+ <% if (data.displayPostPictures()) { %>
<% } %> <% } // end if %> <% if (data.showAdvanced()) { %>