diff --git a/conf-sso/dynamo.xml b/conf-sso/dynamo.xml
index 5dbb8f4..5dcce42 100644
--- a/conf-sso/dynamo.xml
+++ b/conf-sso/dynamo.xml
@@ -66,6 +66,8 @@
- srm
- data
+ - nscache
+ - users
diff --git a/conf/dynamo-venice.xml b/conf/dynamo-venice.xml
index 37b6eef..f38ea6d 100644
--- a/conf/dynamo-venice.xml
+++ b/conf/dynamo-venice.xml
@@ -66,6 +66,8 @@
- srm
- data
+ - nscache
+ - users
diff --git a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceImpl.java b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceImpl.java
index e65b249..231327d 100644
--- a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceImpl.java
+++ b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceImpl.java
@@ -19,45 +19,157 @@ package com.silverwrist.venice.conf.impl;
import java.security.acl.*;
import java.util.*;
+import org.apache.log4j.Logger;
+import org.apache.commons.collections.*;
+import com.silverwrist.dynamo.db.NamespaceCache;
+import com.silverwrist.dynamo.db.UserManagement;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.except.*;
+import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
+import com.silverwrist.dynamo.util.*;
+import com.silverwrist.venice.conf.ConfNamespaces;
import com.silverwrist.venice.conf.iface.*;
import com.silverwrist.venice.conf.obj.*;
class ConferenceImpl implements VeniceConference
{
+ /*--------------------------------------------------------------------------------
+ * Static data members
+ *--------------------------------------------------------------------------------
+ */
+
+ private static Logger logger = Logger.getLogger(ConferenceImpl.class);
+
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
- private DynamicImplConference m_dobj;
- private ConferenceOps m_ops;
- private int m_confid;
- private java.util.Date m_createdate;
- private java.util.Date m_lastupdate;
- private int m_hosts_gid;
- private int m_aclid;
- private String m_name;
+ private DynamicImplConference m_dobj; // used to implement DynamicObject methods
+ private ConferenceOps m_ops; // conference database operations
+ private NamespaceCache m_nscache; // namespace cache object
+ private SecurityReferenceMonitor m_srm; // security reference monitor
+ private UserManagement m_users; // user management object
+ private int m_id; // conference ID
+ private java.util.Date m_createdate; // creation date
+ private java.util.Date m_lastupdate; // last update date
+ private int m_hosts_gid; // GID of community hosts group
+ private int m_aclid; // ACL ID
+ private String m_name; // conference name
+ private ReferenceMap m_properties; // properties cache
+ private String m_prime_alias = null; // primary alias
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
- ConferenceImpl(ConferenceOps ops, Map params)
+ ConferenceImpl(ConferenceOps ops, NamespaceCache nscache, SecurityReferenceMonitor srm, UserManagement users,
+ Map params)
{
m_dobj = new DynamicImplConference(this);
m_ops = ops;
- m_confid = ((Integer)(params.get(ConferenceManagerOps.KEY_CONFID))).intValue();
+ m_nscache = nscache;
+ m_srm = srm;
+ m_users = users;
+ m_id = ((Integer)(params.get(ConferenceManagerOps.KEY_CONFID))).intValue();
m_createdate = (java.util.Date)(params.get(ConferenceManagerOps.KEY_CREATE_DATE));
m_lastupdate = (java.util.Date)(params.get(ConferenceManagerOps.KEY_LAST_UPDATE));
m_hosts_gid = ((Integer)(params.get(ConferenceManagerOps.KEY_HOSTS_GID))).intValue();
m_aclid = ((Integer)(params.get(ConferenceManagerOps.KEY_ACLID))).intValue();
m_name = (String)(params.get(ConferenceManagerOps.KEY_NAME));
+ m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
} // end constructor
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Performs a permission check on the conference's ACL, as well as the global ACL. Returns without
+ * incident if the permission check succeeds; throws a
+ * {@link com.silverwrist.dynamo.except.DynamoSecurityException DynamoSecurityException} if it fails.
+ *
+ * @param caller The user making the call, to test the permission.
+ * @param perm_namespace The namespace of the permission to be tested.
+ * @param perm_name The name of the permission to be tested.
+ * @param fail_message The message to be thrown as a DynamoSecurityException
if the test fails.
+ * Interpreted as a message identifier within the ConferenceMessages
resource
+ * bundle, with one parameter: the name of the conference.
+ * @exception com.silverwrist.dynamo.except.DatabaseException If there was a database failure testing the permission.
+ * @exception com.silverwrist.dynamo.except.DynamoSecurityException If the permission test failed.
+ */
+ private final void testPermission(DynamoUser caller, String perm_namespace, String perm_name,
+ String fail_message) throws DatabaseException, DynamoSecurityException
+ {
+ try
+ { // perform security tests...
+ if (caller.equals(m_srm.getAdminUser()))
+ return; // Administrator can do anything
+ if (m_srm.getAcl(m_aclid).testPermission(caller,perm_namespace,perm_name))
+ return; // we have the right permission in the conference ACL
+ if (m_srm.getGlobalAcl().testPermission(caller,perm_namespace,perm_name))
+ return; // or we can be authorized by the global ACL
+
+ } // end try
+ catch (AclNotFoundException e)
+ { // just fall through and throw the exception
+ } // end catch
+
+ // throw the DynamoSecurityException
+ DynamoSecurityException d = new DynamoSecurityException(ConferenceImpl.class,"ConferenceMessages",fail_message);
+ d.setParameter(0,m_name);
+ throw d;
+
+ } // end testPermission
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class Object
+ *--------------------------------------------------------------------------------
+ */
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param o The reference object with which to compare.
+ * @return true
if this object is the same as the o
argument; false
otherwise.
+ */
+ public boolean equals(Object o)
+ {
+ if (o==null)
+ return false;
+ if (o instanceof VeniceConference)
+ return (((VeniceConference)o).getConfID()==m_id);
+ return false;
+
+ } // end equals
+
+ /**
+ * Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those
+ * provided by {@link java.util.Hashtable Hashtable}.
+ *
+ * @return A hash code value for this object.
+ */
+ public int hashCode()
+ {
+ return m_id;
+
+ } // end hashCode
+
+ /**
+ * Returns a string representation of the object. In general, the toString
method returns a string
+ * that "textually represents" this object.
+ *
+ * @return A string representation of the object.
+ */
+ public String toString()
+ {
+ return "Conference \"" + m_name + "\"";
+
+ } // end toString
+
/*--------------------------------------------------------------------------------
* Implementations from interface DynamicObject
*--------------------------------------------------------------------------------
@@ -123,9 +235,49 @@ class ConferenceImpl implements VeniceConference
*/
public Object getObject(String namespace, String name)
{
- return null; // TEMP
+ if (logger.isDebugEnabled())
+ logger.debug("Conference.getObject: namespace = " + namespace + ", name = " + name);
+ try
+ { // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_nscache.namespaceNameToId(namespace),name);
+ Object rc = null;
+ synchronized (this)
+ { // start by looking in the properties map
+ rc = m_properties.get(key);
+ if (rc==null)
+ { // no use - need to try the database
+ rc = m_ops.getProperty(m_id,key);
+ if (rc!=null)
+ { // found in the database
+ m_properties.put(key,rc);
+ logger.debug("value found in database");
- }
+ } // end if
+
+ } // end if
+ else
+ logger.debug("value found in cache");
+
+ } // end synchronized block
+
+ if (rc==null)
+ { // the object was not found
+ logger.debug("value not found");
+ throw new NoSuchObjectException(this.toString(),namespace,name);
+
+ } // end if
+
+ return rc;
+
+ } // end try
+ catch (DatabaseException e)
+ { // translate into our NoSuchObjectException but retain the DatabaseException
+ logger.debug("Database exception while doing find",e);
+ throw new NoSuchObjectException(this.toString(),namespace,name,e);
+
+ } // end catch
+
+ } // end getObject
/*--------------------------------------------------------------------------------
* Implementations from interface SecureObjectStore
@@ -148,9 +300,27 @@ class ConferenceImpl implements VeniceConference
public Object setObject(DynamoUser caller, String namespace, String name, Object value)
throws DatabaseException, DynamoSecurityException
{
- return null; // TEMP
+ testPermission(caller,namespace,"set.property","auth.setProperty");
+ DateObjectPair rc = null;
- }
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_nscache.namespaceNameToId(namespace),name);
+ synchronized (this)
+ { // start by setting the database value
+ rc = m_ops.setProperty(m_id,key,value);
+
+ // and cache it, too
+ m_properties.put(key,value);
+
+ // and save off the update date/time
+ m_lastupdate = rc.getDate();
+
+ } // end synchronized block
+
+ // TODO: m_post.postUpdate(new CommunityPropertyUpdateEvent(this,namespace,name));
+ return rc.getObject();
+
+ } // end setObject
/**
* Removes an object from this SecureObjectStore
.
@@ -167,9 +337,27 @@ class ConferenceImpl implements VeniceConference
public Object removeObject(DynamoUser caller, String namespace, String name)
throws DatabaseException, DynamoSecurityException
{
- return null; // TEMP
+ testPermission(caller,namespace,"remove.property","auth.removeProperty");
+ DateObjectPair rc = null;
- }
+ // convert the namespace name to an ID here
+ PropertyKey key = new PropertyKey(m_nscache.namespaceNameToId(namespace),name);
+ synchronized (this)
+ { // start by killing the database value
+ rc = m_ops.removeProperty(m_id,key);
+
+ // and remove the cached value, too
+ m_properties.remove(key);
+
+ if (rc!=null) // save off update date.time
+ m_lastupdate = rc.getDate();
+
+ } // end synchronized block
+
+ // TODO: m_post.postUpdate(new CommunityPropertyUpdateEvent(this,namespace,name));
+ return (rc==null) ? null : rc.getObject();
+
+ } // end removeObject
/**
* Returns a collection of all object namespaces that have been set into this SecureObjectStore
.
@@ -180,9 +368,15 @@ class ConferenceImpl implements VeniceConference
*/
public Collection getNamespaces() throws DatabaseException
{
- return null; // TEMP
+ // call through to the database to get the list of namespace IDs
+ int[] ids = m_ops.getPropertyNamespaceIDs(m_id);
- }
+ ArrayList rc = new ArrayList(ids.length);
+ for (int i=0; iSecureObjectStore under
@@ -195,9 +389,28 @@ class ConferenceImpl implements VeniceConference
*/
public Collection getNamesForNamespace(String namespace) throws DatabaseException
{
- return null; // TEMP
+ // call through to the database to get the data for this namespace
+ int nsid = m_nscache.namespaceNameToId(namespace);
+ Map data = m_ops.getAllProperties(m_id,nsid);
- }
+ // we both create the return value and cache the data values
+ ArrayList rc = new ArrayList(data.size());
+ synchronized (this)
+ { // do the transfer...
+ Iterator it = data.entrySet().iterator();
+ while (it.hasNext())
+ { // copy one entry at a time
+ Map.Entry ntry = (Map.Entry)(it.next());
+ rc.add(ntry.getKey().toString());
+ m_properties.put(new PropertyKey(nsid,ntry.getKey().toString()),ntry.getValue());
+
+ } // end while
+
+ } // end synchronized block
+
+ return Collections.unmodifiableList(rc);
+
+ } // end getNamesForNamespace
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceConference
@@ -206,13 +419,22 @@ class ConferenceImpl implements VeniceConference
public int getConfID()
{
- return m_confid;
+ return m_id;
} // end getConfID
public void setName(DynamoUser caller, String name) throws DatabaseException, DynamoSecurityException
{
- }
+ testPermission(caller,ConfNamespaces.PERMISSIONS_NAMESPACE,"set.name","auth.setName");
+ synchronized (this)
+ { // update the name
+ java.util.Date updated = m_ops.setName(m_id,name);
+ m_name = name;
+ m_lastupdate = updated;
+
+ } // end synchronized block
+
+ } // end setName
public java.util.Date getCreatedDate()
{
@@ -226,10 +448,13 @@ class ConferenceImpl implements VeniceConference
} // end getLastUpdateDate
- public void setLastUpdateDate(DynamoUser caller, java.util.Date date)
+ public synchronized void setLastUpdateDate(DynamoUser caller, java.util.Date date)
throws DatabaseException, DynamoSecurityException
{
- }
+ m_ops.setLastUpdateDate(m_id,date);
+ m_lastupdate = date;
+
+ } // end setLastUpdateDate
public int getHostsGID()
{
@@ -239,38 +464,68 @@ class ConferenceImpl implements VeniceConference
public DynamoGroup getHosts() throws DatabaseException
{
- return null; // TEMP
+ return m_users.getGroup(m_hosts_gid);
- }
+ } // end getHosts
public DynamoAcl getAcl() throws DatabaseException, AclNotFoundException
{
- return null; // TEMP
+ return m_srm.getAcl(m_aclid);
- }
+ } // end getAcl
public Set getAliases() throws DatabaseException
{
- return null; // TEMP
+ return m_ops.getAliases(m_id);
- }
+ } // end getAliases
- public String getPrimaryAlias() throws DatabaseException
+ public synchronized String getPrimaryAlias() throws DatabaseException
{
- return null; // TEMP
+ if (m_prime_alias==null)
+ m_prime_alias = m_ops.getPrimaryAlias(m_id);
+ return m_prime_alias;
- }
+ } // end getPrimaryAlias
public void setPrimaryAlias(DynamoUser caller, String alias) throws DatabaseException, DynamoSecurityException
{
- }
+ testPermission(caller,ConfNamespaces.PERMISSIONS_NAMESPACE,"set.alias","auth.setAlias");
+ synchronized (this)
+ { // change the prime alias
+ java.util.Date update = m_ops.setPrimaryAlias(m_id,alias);
+ m_prime_alias = alias;
+ if (update!=null)
+ m_lastupdate = update;
+
+ } // end synchronized block
+
+ } // end setPrimaryAlias
public void addAlias(DynamoUser caller, String alias) throws DatabaseException, DynamoSecurityException
{
- }
+ testPermission(caller,ConfNamespaces.PERMISSIONS_NAMESPACE,"set.alias","auth.setAlias");
+ synchronized (this)
+ { // add an alias
+ java.util.Date update = m_ops.addAlias(m_id,alias);
+ if (update!=null)
+ m_lastupdate = update;
+
+ } // end synchronized block
+
+ } // end addAlias
public void removeAlias(DynamoUser caller, String alias) throws DatabaseException, DynamoSecurityException
{
- }
+ testPermission(caller,ConfNamespaces.PERMISSIONS_NAMESPACE,"set.alias","auth.setAlias");
+ synchronized (this)
+ { // remove the alias
+ java.util.Date update = m_ops.removeAlias(m_id,alias);
+ if (update!=null)
+ m_lastupdate = update;
+
+ } // end synchronized block
+
+ } // end removeAlias
} // end class ConferenceImpl
diff --git a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceManager.java b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceManager.java
index 988ee2c..20fb7c3 100644
--- a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceManager.java
+++ b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceManager.java
@@ -20,8 +20,11 @@ package com.silverwrist.venice.conf.impl;
import java.security.acl.AclNotFoundException;
import java.util.*;
import org.apache.commons.collections.*;
+import com.silverwrist.dynamo.db.NamespaceCache;
+import com.silverwrist.dynamo.db.UserManagement;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
import com.silverwrist.venice.iface.*;
import com.silverwrist.venice.conf.ConfNamespaces;
import com.silverwrist.venice.conf.iface.*;
@@ -37,6 +40,9 @@ public class ConferenceManager implements ConferenceAccessObject
private DynamicImplConferenceAccess m_dobj;
private UseCount m_uc;
private ConferenceManagerOps m_ops;
+ private NamespaceCache m_nscache;
+ private SecurityReferenceMonitor m_srm;
+ private UserManagement m_users; // user management object
private ReferenceMap m_confs;
/*--------------------------------------------------------------------------------
@@ -44,7 +50,8 @@ public class ConferenceManager implements ConferenceAccessObject
*--------------------------------------------------------------------------------
*/
- public ConferenceManager(UseCount uc, DBConnectionPool pool) throws ModuleException
+ public ConferenceManager(UseCount uc, DBConnectionPool pool, NamespaceCache nscache, SecurityReferenceMonitor srm,
+ UserManagement users) throws ModuleException
{
try
{ // initialize everything
@@ -56,10 +63,14 @@ public class ConferenceManager implements ConferenceAccessObject
} // end try
catch (ConfigException e)
{ // convert it to a ModuleException
+ uc.decrementUseCount();
throw new ModuleException(e);
} // end catch
+ m_nscache = nscache;
+ m_srm = srm;
+ m_users = users;
m_confs = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
} // end constructor
@@ -75,7 +86,7 @@ public class ConferenceManager implements ConferenceAccessObject
ConferenceImpl rc = (ConferenceImpl)(m_confs.get(key));
if (rc==null)
{ // create a new conference implementation object and save it
- rc = new ConferenceImpl(m_ops.getConferenceOps(),params);
+ rc = new ConferenceImpl(m_ops.getConferenceOps(),m_nscache,m_srm,m_users,params);
m_confs.put(key,rc);
} // end if
@@ -238,6 +249,9 @@ public class ConferenceManager implements ConferenceAccessObject
public void dispose()
{
+ m_nscache = null;
+ m_srm = null;
+ m_users = null;
m_ops.dispose();
m_ops = null;
m_uc.decrementUseCount();
diff --git a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceMessages.properties b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceMessages.properties
index bc0619f..01daf9e 100644
--- a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceMessages.properties
+++ b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceMessages.properties
@@ -20,3 +20,12 @@ confid.notfound=No conference was found with conference ID #{0}.
confalias.notfound=No conference was found with conference alias "{0}."
confid.comm.notfound=No conference was found with conference ID #{0} in community "{1}."
confalias.comm.notfound=No conference was found with conference alias "{0}" in community "{1}."
+property.serialize=The value of property "{0}" could not be serialized.
+property.deserialize=The value of property "{0}" could not be deserialized.
+auth.setProperty=You are not authorized to set properties on the conference "{0}."
+auth.removeProperty=You are not authorized to remove properties from the conference "{0}."
+auth.setName=You are not authorized to change the name of the conference "{0}."
+auth.setAlias=You are not authorized to change the aliases of the conference "{0}."
+no.remove.prime=You cannot remove the primary alias from a conference.
+auth.sequence=You are not authorized to change the sequencing of conferences.
+auth.hide.show=You are not permitted to hide or show conferences in this community.
diff --git a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceOps.java b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceOps.java
index 7ee5473..dcc6850 100644
--- a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceOps.java
+++ b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceOps.java
@@ -21,6 +21,7 @@ import java.util.*;
import com.silverwrist.dynamo.db.OpsBase;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
+import com.silverwrist.dynamo.util.*;
abstract class ConferenceOps extends OpsBase
{
@@ -40,4 +41,28 @@ abstract class ConferenceOps extends OpsBase
*--------------------------------------------------------------------------------
*/
+ abstract Object getProperty(int confid, PropertyKey key) throws DatabaseException;
+
+ abstract DateObjectPair setProperty(int confid, PropertyKey key, Object value) throws DatabaseException;
+
+ abstract DateObjectPair removeProperty(int confid, PropertyKey key) throws DatabaseException;
+
+ abstract int[] getPropertyNamespaceIDs(int confid) throws DatabaseException;
+
+ abstract Map getAllProperties(int confid, int namespace) throws DatabaseException;
+
+ abstract java.util.Date setName(int confid, String name) throws DatabaseException;
+
+ abstract void setLastUpdateDate(int confid, java.util.Date date) throws DatabaseException;
+
+ abstract Set getAliases(int confid) throws DatabaseException;
+
+ abstract String getPrimaryAlias(int confid) throws DatabaseException;
+
+ abstract java.util.Date setPrimaryAlias(int confid, String alias) throws DatabaseException;
+
+ abstract java.util.Date addAlias(int confid, String alias) throws DatabaseException;
+
+ abstract java.util.Date removeAlias(int confid, String alias) throws DatabaseException;
+
} // end class ConferenceOps
diff --git a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceOps_mysql.java b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceOps_mysql.java
index 72cd16b..26a8954 100644
--- a/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceOps_mysql.java
+++ b/src/conferencing-module/com/silverwrist/venice/conf/impl/ConferenceOps_mysql.java
@@ -26,6 +26,14 @@ import com.silverwrist.dynamo.util.*;
class ConferenceOps_mysql extends ConferenceOps
{
+ /*--------------------------------------------------------------------------------
+ * Attributes
+ *--------------------------------------------------------------------------------
+ */
+
+ private DBUtilities m_utils; // reference to utilities object
+ private PropertySerializer m_psz; // reference to property serializer
+
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
@@ -34,12 +42,681 @@ class ConferenceOps_mysql extends ConferenceOps
ConferenceOps_mysql(DBConnectionPool pool)
{
super(pool);
+ m_utils = (DBUtilities)(pool.queryService(DBUtilities.class));
+ m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class));
} // end constructor
+ /*--------------------------------------------------------------------------------
+ * Internal operations
+ *--------------------------------------------------------------------------------
+ */
+
+ private final java.util.Date touchConference(Connection conn, int confid, java.util.Date date) throws SQLException
+ {
+ PreparedStatement stmt = null;
+ try
+ { // prepare and execute the update statement
+ stmt = conn.prepareStatement("UPDATE conferences SET lastupdate = ? WHERE confid = ?;");
+ m_utils.setDateTime(stmt,1,date);
+ stmt.setInt(2,confid);
+ stmt.executeUpdate();
+ return date;
+
+ } // end try
+ finally
+ { // make sure and close out the statement
+ SQLUtils.shutdown(stmt);
+
+ } // end finally
+
+ } // end touchConference
+
+ private final java.util.Date touchConference(Connection conn, int confid) throws SQLException
+ {
+ return this.touchConference(conn,confid,new java.util.Date());
+
+ } // end touchConference
+
+ /*--------------------------------------------------------------------------------
+ * Overrides from class OpsBase
+ *--------------------------------------------------------------------------------
+ */
+
+ public void dispose()
+ {
+ m_psz = null;
+ m_utils = null;
+ super.dispose();
+
+ } // end dispose
+
/*--------------------------------------------------------------------------------
* Abstract implementations from class ConferenceOps
*--------------------------------------------------------------------------------
*/
+ Object getProperty(int confid, PropertyKey key) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ String rc_str = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // look up the property
+ stmt = conn.prepareStatement("SELECT prop_value FROM conf_props WHERE confid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setInt(1,confid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ rs = stmt.executeQuery();
+ if (!(rs.next()))
+ return null; // property not found
+
+ rc_str = rs.getString(1);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(rc_str);
+ if (rc!=null)
+ return rc;
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(ConferenceOps_mysql.class,"ConferenceMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end getProperty
+
+ DateObjectPair setProperty(int confid, PropertyKey key, Object value) throws DatabaseException
+ {
+ String serialized_value = m_psz.serializeProperty(value);
+ if (serialized_value==null)
+ { // serialization exception - throw it
+ DatabaseException de = new DatabaseException(ConferenceOps_mysql.class,"ConferenceMessages",
+ "property.serialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end if
+
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ java.util.Date update = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES conf_props WRITE, conferences WRITE;");
+
+ // look to see if the property value is already there
+ stmt = conn.prepareStatement("SELECT prop_value FROM conf_props WHERE confid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setInt(1,confid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ if (old_value!=null)
+ { // prepare the statement to update the existing record
+ stmt = conn.prepareStatement("UPDATE conf_props SET prop_value = ? WHERE confid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setString(1,serialized_value);
+ stmt.setInt(2,confid);
+ stmt.setInt(3,key.getNamespaceID());
+ stmt.setString(4,key.getName());
+
+ } // end if
+ else
+ { // prepare the statement to insert a new record
+ stmt = conn.prepareStatement("INSERT INTO conf_props (confid, nsid, prop_name, prop_value) "
+ + "VALUES (?, ?, ?, ?);");
+ stmt.setInt(1,confid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ stmt.setString(4,serialized_value);
+
+ } // end else
+
+ stmt.executeUpdate(); // execute it!
+
+ // Touch the conference entry.
+ update = touchConference(conn,confid);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ if (old_value==null)
+ return new DateObjectPair(null,update); // no previous value
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(old_value);
+ if (rc!=null)
+ return new DateObjectPair(rc,update);
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(ConferenceOps_mysql.class,"ConferenceMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end setProperty
+
+ DateObjectPair removeProperty(int confid, PropertyKey key) throws DatabaseException
+ {
+ String old_value = null;
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ Statement stmt2 = null;
+ ResultSet rs = null;
+ java.util.Date update = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // lock the table
+ stmt2 = conn.createStatement();
+ stmt2.executeUpdate("LOCK TABLES conf_props WRITE, conferences WRITE;");
+
+ // look to see if the property value is already there
+ stmt = conn.prepareStatement("SELECT prop_value FROM conf_props WHERE confid = ? AND nsid = ? "
+ + "AND prop_name = ?;");
+ stmt.setInt(1,confid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ rs = stmt.executeQuery();
+ if (rs.next())
+ old_value = rs.getString(1);
+ else
+ return null; // no need to remove anything
+
+ SQLUtils.shutdown(rs);
+ rs = null;
+ SQLUtils.shutdown(stmt);
+
+ // delete the database row
+ stmt = conn.prepareStatement("DELETE FROM conf_props WHERE confid = ? AND nsid = ? AND prop_name = ?;");
+ stmt.setInt(1,confid);
+ stmt.setInt(2,key.getNamespaceID());
+ stmt.setString(3,key.getName());
+ stmt.executeUpdate();
+
+ // Touch the conference entry.
+ update = touchConference(conn,confid);
+
+ } // end try
+ catch (SQLException e)
+ { // translate to a general DatabaseException
+ throw generalException(e);
+
+ } // end catch
+ finally
+ { // shut everything down
+ MySQLUtils.unlockTables(conn);
+ SQLUtils.shutdown(rs);
+ SQLUtils.shutdown(stmt);
+ SQLUtils.shutdown(stmt2);
+ SQLUtils.shutdown(conn);
+
+ } // end finally
+
+ // Deserialize the property value.
+ Object rc = m_psz.deserializeProperty(old_value);
+ if (rc!=null)
+ return new DateObjectPair(rc,update);
+
+ // deserialization exception - throw it
+ DatabaseException de = new DatabaseException(ConferenceOps_mysql.class,"ConferenceMessages",
+ "property.deserialize");
+ de.setParameter(0,key.getName());
+ throw de;
+
+ } // end removeProperty
+
+ int[] getPropertyNamespaceIDs(int confid) throws DatabaseException
+ {
+ Connection conn = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try
+ { // get a connection
+ conn = getConnection();
+
+ // execute the query!
+ stmt = conn.prepareStatement("SELECT DISTINCT nsid FROM conf_props WHERE confid = ?;");
+ stmt.setInt(1,confid);
+ rs = stmt.executeQuery();
+
+ // read out a list of the namespace IDs
+ ArrayList tmp = new ArrayList();
+ while (rs.next())
+ tmp.add(new Integer(rs.getInt(1)));
+
+ // create and return the array
+ int[] rc = new int[tmp.size()];
+ for (int i=0; i