added the initial implementation of the Universal Message Store (UniStore)
This commit is contained in:
parent
bbd46e4dc7
commit
7727dc61dd
|
@ -94,6 +94,13 @@
|
|||
</dictionary>
|
||||
</object>
|
||||
|
||||
<object name="unistore" classname="com.silverwrist.dynamo.unistore.UniStoreManager" priority="5">
|
||||
<database connection="data" namespaces="nscache"/>
|
||||
<security object="srm"/>
|
||||
<user-manager object="users"/>
|
||||
<message-cache hardlimit="100" softlimit="1000"/>
|
||||
</object>
|
||||
|
||||
<!-- Presentation and interface objects -->
|
||||
<object name="remapper" classname="com.silverwrist.dynamo.servlet.RemapperData" priority="0">
|
||||
<remap path="/verifyemail">
|
||||
|
|
|
@ -93,6 +93,13 @@
|
|||
</dictionary>
|
||||
</object>
|
||||
|
||||
<object name="unistore" classname="com.silverwrist.dynamo.unistore.UniStoreManager" priority="5">
|
||||
<database connection="data" namespaces="nscache"/>
|
||||
<security object="srm"/>
|
||||
<user-manager object="users"/>
|
||||
<message-cache hardlimit="100" softlimit="1000"/>
|
||||
</object>
|
||||
|
||||
<!-- Presentation and interface objects -->
|
||||
<object name="remapper" classname="com.silverwrist.dynamo.servlet.RemapperData" priority="0">
|
||||
<remap path="/verifyemail">
|
||||
|
|
|
@ -274,7 +274,7 @@ CREATE TABLE us_text (
|
|||
last_read DATETIME, # timestamp of when it was last read
|
||||
data MEDIUMTEXT, # the text (16 Mb available)
|
||||
PRIMARY KEY (msgid, part),
|
||||
INDEX by_name (msgid, ident_nsid, ident_name)
|
||||
UNIQUE INDEX by_name (msgid, ident_nsid, ident_name)
|
||||
);
|
||||
|
||||
# UniStore: Text message part properties
|
||||
|
@ -300,7 +300,7 @@ CREATE TABLE us_binary (
|
|||
last_read DATETIME, # timestamp of when it was last read
|
||||
data MEDIUMBLOB, # the actual data (16 Mb of space available)
|
||||
PRIMARY KEY (msgid, part),
|
||||
INDEX by_name (msgid, ident_nsid, ident_name)
|
||||
UNIQUE INDEX by_name (msgid, ident_nsid, ident_name)
|
||||
);
|
||||
|
||||
# UniStore: Binary message part properties
|
||||
|
|
148
src/baseutil/com/silverwrist/util/CacheInputStream.java
Normal file
148
src/baseutil/com/silverwrist/util/CacheInputStream.java
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.util;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class CacheInputStream extends FilterInputStream
|
||||
{
|
||||
/*---------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static final int MAX_MEMORY = 65536;
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private File m_tempfile = null;
|
||||
private int m_length = 0;
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public CacheInputStream(String temp_prefix, InputStream data) throws IOException
|
||||
{
|
||||
super(new ByteArrayInputStream(new byte[0])); // dummy value
|
||||
|
||||
boolean complete = false;
|
||||
OutputStream imstm = null;
|
||||
try
|
||||
{ // Copy data to a temporary stream.
|
||||
ByteArrayOutputStream imstm_byte = new ByteArrayOutputStream();
|
||||
imstm = imstm_byte;
|
||||
byte[] buf = new byte[4096];
|
||||
int rd = data.read(buf);
|
||||
while (rd>=0)
|
||||
{ // a simple copy loop, but with a twist
|
||||
if (rd>0)
|
||||
{ // if we go over memory limits, we'll have to create a tempfile
|
||||
// and spill there...
|
||||
if ((imstm_byte!=null) && ((rd + m_length)>MAX_MEMORY))
|
||||
{ // get the source for the copy
|
||||
ByteArrayInputStream copy_src =
|
||||
new ByteArrayInputStream(imstm_byte.toByteArray());
|
||||
|
||||
// get the destination for the copy
|
||||
m_tempfile = File.createTempFile(temp_prefix,null);
|
||||
imstm = new FileOutputStream(m_tempfile);
|
||||
|
||||
// copy it and close the byte stream
|
||||
IOUtils.copy(copy_src,imstm);
|
||||
IOUtils.shutdown(copy_src);
|
||||
IOUtils.shutdown(imstm_byte);
|
||||
imstm_byte = null;
|
||||
|
||||
} // end if
|
||||
|
||||
// write data to the intermediate stream
|
||||
imstm.write(buf,0,rd);
|
||||
m_length += rd;
|
||||
|
||||
} // end if
|
||||
|
||||
rd = data.read(buf);
|
||||
|
||||
} // end while
|
||||
|
||||
if (imstm_byte!=null)
|
||||
this.in = new ByteArrayInputStream(imstm_byte.toByteArray());
|
||||
else
|
||||
{ // close the file output stream, create a file input stream
|
||||
IOUtils.shutdown(imstm);
|
||||
imstm = null;
|
||||
this.in = new FileInputStream(m_tempfile);
|
||||
|
||||
} // end else
|
||||
|
||||
complete = true;
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // close down the intermediate stream
|
||||
IOUtils.shutdown(imstm);
|
||||
if (!complete && (m_tempfile!=null))
|
||||
{ // delete the temporary file
|
||||
m_tempfile.delete();
|
||||
m_tempfile = null;
|
||||
|
||||
} // end if
|
||||
|
||||
} // end finally
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Overrides from class FilterInputStream
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void close() throws IOException
|
||||
{
|
||||
try
|
||||
{ // call through and close the stream
|
||||
super.close();
|
||||
|
||||
} // end try
|
||||
finally
|
||||
{ // delete the temp file as well
|
||||
if (m_tempfile!=null)
|
||||
m_tempfile.delete();
|
||||
m_tempfile = null;
|
||||
|
||||
} // end finally
|
||||
|
||||
} // end close
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* External operations
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int getLength()
|
||||
{
|
||||
return m_length;
|
||||
|
||||
} // end getLength
|
||||
|
||||
} // end class CacheInputStream
|
|
@ -86,4 +86,10 @@ public interface Namespaces
|
|||
public static final String SPELLCHECKER_PROPERTIES_NAMESPACE =
|
||||
"http://www.silverwrist.com/NS/dynamo/2003/06/07/spellchecker.properties";
|
||||
|
||||
/**
|
||||
* Namespace for the permissions for the Universal Message Store (UniStore).
|
||||
*/
|
||||
public static final String UNISTORE_PERMISSIONS_NAMESPACE =
|
||||
"http://www.silverwrist.com/NS/dynamo/2003/06/10/unistore.permissions";
|
||||
|
||||
} // end interface Namespaces
|
||||
|
|
|
@ -3,6 +3,7 @@ advogato
|
|||
ain't
|
||||
anime
|
||||
anla'shok
|
||||
avaltus
|
||||
bajor
|
||||
bios
|
||||
boitano
|
||||
|
@ -22,6 +23,7 @@ cst
|
|||
deflector
|
||||
deflectors
|
||||
delenn
|
||||
denise
|
||||
didn't
|
||||
dilithium
|
||||
docking
|
||||
|
@ -39,10 +41,12 @@ faux
|
|||
fett
|
||||
followup
|
||||
franklin
|
||||
fsck
|
||||
fucking
|
||||
gamey
|
||||
hairstyle
|
||||
hairstyles
|
||||
harasser
|
||||
hasn't
|
||||
haven't
|
||||
he'd
|
||||
|
@ -52,6 +56,7 @@ i'd
|
|||
i'll
|
||||
i'm
|
||||
i've
|
||||
imho
|
||||
inducers
|
||||
it'd
|
||||
khan
|
||||
|
@ -86,6 +91,7 @@ privs
|
|||
propping
|
||||
psi
|
||||
pst
|
||||
quid
|
||||
refit
|
||||
refitting
|
||||
replicator
|
||||
|
@ -115,6 +121,7 @@ starfleet
|
|||
starship
|
||||
straightening
|
||||
stunted
|
||||
tarred
|
||||
terrence
|
||||
they're
|
||||
turbolift
|
||||
|
@ -126,6 +133,7 @@ url
|
|||
utne
|
||||
valen
|
||||
veni
|
||||
wasn't
|
||||
we'll
|
||||
we're
|
||||
we've
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.iface;
|
||||
|
||||
import com.silverwrist.dynamo.except.DatabaseException;
|
||||
|
||||
public interface UniStore
|
||||
{
|
||||
public UniStoreMessage getMessage(long msgid) throws DatabaseException;
|
||||
|
||||
} // end interface UniStore
|
|
@ -18,13 +18,14 @@
|
|||
package com.silverwrist.dynamo.iface;
|
||||
|
||||
import java.io.Reader;
|
||||
import com.silverwrist.dynamo.except.DatabaseException;
|
||||
|
||||
public interface UniStoreTextPart extends UniStorePart
|
||||
{
|
||||
public int getLineCount();
|
||||
|
||||
public String getText();
|
||||
public String getText() throws DatabaseException;
|
||||
|
||||
public Reader getTextAsReader();
|
||||
public Reader getTextAsReader() throws DatabaseException;
|
||||
|
||||
} // end interface UniStoreTextPart
|
||||
|
|
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.Blob;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import org.apache.commons.collections.*;
|
||||
import com.silverwrist.dynamo.db.NamespaceCache;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
import com.silverwrist.dynamo.util.*;
|
||||
|
||||
class BinaryPartImpl implements UniStoreBinaryPart
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Internal class implementing a Blob return
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private class ReturnBlob implements Blob
|
||||
{
|
||||
/*====================================================================
|
||||
* Attributes
|
||||
*====================================================================
|
||||
*/
|
||||
|
||||
private byte[] m_data; // the actual blob data
|
||||
|
||||
/*====================================================================
|
||||
* Constructor
|
||||
*====================================================================
|
||||
*/
|
||||
|
||||
ReturnBlob(byte[] data)
|
||||
{
|
||||
m_data = data;
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*====================================================================
|
||||
* Implementations from interface Blob
|
||||
*====================================================================
|
||||
*/
|
||||
|
||||
public long length()
|
||||
{
|
||||
return m_size;
|
||||
|
||||
} // end length
|
||||
|
||||
public byte[] getBytes(long pos, int length) throws SQLException
|
||||
{
|
||||
if ((pos<1) || (pos>(long)m_size))
|
||||
throw new SQLException("invalid position value");
|
||||
if ((length<=0) || ((pos + length - 1)>(long)m_size))
|
||||
throw new SQLException("invalid length value");
|
||||
byte[] rc = new byte[length];
|
||||
System.arraycopy(m_data,(int)pos,rc,0,length);
|
||||
return rc;
|
||||
|
||||
} // end getBytes
|
||||
|
||||
public InputStream getBinaryStream()
|
||||
{
|
||||
return new ByteArrayInputStream(m_data);
|
||||
|
||||
} // end getBinaryStream
|
||||
|
||||
public long position(byte[] pattern, long start) throws SQLException
|
||||
{
|
||||
throw new SQLException("position() method not implemented");
|
||||
|
||||
} // end position
|
||||
|
||||
public long position(Blob pattern, long start) throws SQLException
|
||||
{
|
||||
throw new SQLException("position() method not implemented");
|
||||
|
||||
} // end position
|
||||
|
||||
public int setBytes(long pos, byte[] bytes) throws SQLException
|
||||
{
|
||||
throw new SQLException("setBytes() method not implemented");
|
||||
|
||||
} // end setBytes
|
||||
|
||||
public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException
|
||||
{
|
||||
throw new SQLException("setBytes() method not implemented");
|
||||
|
||||
} // end setBytes
|
||||
|
||||
public OutputStream setBinaryStream(long pos) throws SQLException
|
||||
{
|
||||
throw new SQLException("setBinaryStream() method not implemented");
|
||||
|
||||
} // end setBinaryStream
|
||||
|
||||
public void truncate(long len) throws SQLException
|
||||
{
|
||||
throw new SQLException("truncate() method not implemented");
|
||||
|
||||
} // end truncate
|
||||
|
||||
} // end class ReturnBlob
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private BinaryPartOps m_ops;
|
||||
private NamespaceCache m_nscache;
|
||||
private MessageImpl m_parent;
|
||||
private int m_part;
|
||||
private QualifiedNameKey m_identity;
|
||||
private String m_mimetype;
|
||||
private int m_size;
|
||||
private String m_filename;
|
||||
private int m_nread;
|
||||
private java.util.Date m_lastread;
|
||||
private ReferenceMap m_properties;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
BinaryPartImpl(BinaryPartOps ops, NamespaceCache nscache, MessageImpl parent, Map params) throws DatabaseException
|
||||
{
|
||||
m_ops = ops;
|
||||
m_nscache = nscache;
|
||||
m_parent = parent;
|
||||
m_part = ((Integer)(params.get(MessageOps.PARAM_PART))).intValue();
|
||||
PropertyKey pk = (PropertyKey)(params.get(MessageOps.PARAM_IDENTITY));
|
||||
m_identity = new QualifiedNameKey(nscache.namespaceIdToName(pk.getNamespaceID()),pk.getName());
|
||||
m_mimetype = (String)(params.get(MessageOps.PARAM_MIMETYPE));
|
||||
Integer tmp = (Integer)(params.get(MessageOps.PARAM_SIZE));
|
||||
if (tmp!=null)
|
||||
m_size = tmp.intValue();
|
||||
m_filename = (String)(params.get(MessageOps.PARAM_FILENAME));
|
||||
m_nread = ((Integer)(params.get(MessageOps.PARAM_READS))).intValue();
|
||||
m_lastread = (java.util.Date)(params.get(MessageOps.PARAM_LASTREAD));
|
||||
m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface ObjectProvider
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves an object from this <CODE>ObjectProvider</CODE>.
|
||||
*
|
||||
* @param namespace The namespace to interpret the name relative to.
|
||||
* @param name The name of the object to be retrieved.
|
||||
* @return The object reference specified.
|
||||
*/
|
||||
public Object getObject(String namespace, String 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_parent.getMessageID(),m_part,key);
|
||||
if (rc!=null)
|
||||
m_properties.put(key,rc);
|
||||
|
||||
} // end if
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
if (rc==null)
|
||||
throw new NoSuchObjectException(this.toString(),namespace,name);
|
||||
return rc;
|
||||
|
||||
} // end try
|
||||
catch (DatabaseException e)
|
||||
{ // translate into our NoSuchObjectException but retain the DatabaseException
|
||||
throw new NoSuchObjectException(this.toString(),namespace,name,e);
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end getObject
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface SecureObjectStore
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets an object into this <CODE>SecureObjectStore</CODE>.
|
||||
*
|
||||
* @param caller The user performing the operation.
|
||||
* @param namespace The namespace to interpret the name relative to.
|
||||
* @param name The name of the object to be set.
|
||||
* @param value The object to set into the <CODE>SecureObjectStore</CODE>.
|
||||
* @return The previous object that was set into the <CODE>SecureObjectStore</CODE> under this namespace and name, or
|
||||
* <CODE>null</CODE> if there was no such object.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error setting the object value.
|
||||
* @exception com.silverwrist.dynamo.except.DynamoSecurityException If the specified user is not permitted to
|
||||
* set this object value into this <CODE>SecureObjectStore</CODE>.
|
||||
*/
|
||||
public Object setObject(DynamoUser caller, String namespace, String name, Object value)
|
||||
throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
m_parent.testPermission(caller,namespace,"set.property","no.setProperty");
|
||||
Object 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_parent.getMessageID(),m_part,key,value);
|
||||
|
||||
// and cache it, too
|
||||
m_properties.put(key,value);
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name));
|
||||
return rc;
|
||||
|
||||
} // end setObject
|
||||
|
||||
/**
|
||||
* Removes an object from this <CODE>SecureObjectStore</CODE>.
|
||||
*
|
||||
* @param caller The user performing the operation.
|
||||
* @param namespace The namespace to interpret the name relative to.
|
||||
* @param name The name of the object to be removed.
|
||||
* @return The previous object that was set into the <CODE>SecureObjectStore</CODE> under this namespace and name, or
|
||||
* <CODE>null</CODE> if there was no such object.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error removing the object value.
|
||||
* @exception com.silverwrist.dynamo.except.DynamoSecurityException If the specified user is not permitted to
|
||||
* remove this object value from this <CODE>SecureObjectStore</CODE>.
|
||||
*/
|
||||
public Object removeObject(DynamoUser caller, String namespace, String name)
|
||||
throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
m_parent.testPermission(caller,namespace,"remove.property","no.removeProperty");
|
||||
Object 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_parent.getMessageID(),m_part,key);
|
||||
|
||||
// and remove the cached value, too
|
||||
m_properties.remove(key);
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name));
|
||||
return rc;
|
||||
|
||||
} // end removeObject
|
||||
|
||||
/**
|
||||
* Returns a collection of all object namespaces that have been set into this <CODE>SecureObjectStore</CODE>.
|
||||
*
|
||||
* @return A {@link java.util.Collection Collection} containing {@link java.lang.String String} objects specifying
|
||||
* all the object namespaces.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error getting the namespace list.
|
||||
*/
|
||||
public Collection getNamespaces() throws DatabaseException
|
||||
{
|
||||
// call through to the database to get the list of namespace IDs
|
||||
int[] ids = m_ops.getPropertyNamespaceIDs(m_parent.getMessageID(),m_part);
|
||||
|
||||
ArrayList rc = new ArrayList(ids.length);
|
||||
for (int i=0; i<ids.length; i++)
|
||||
rc.add(m_nscache.namespaceIdToName(ids[i]));
|
||||
return Collections.unmodifiableList(rc);
|
||||
|
||||
} // end getNamespaces
|
||||
|
||||
/**
|
||||
* Returns a collection of all object names that have been set into this <CODE>SecureObjectStore</CODE> under
|
||||
* a given namespace.
|
||||
*
|
||||
* @param namespace The namespace to look for names under.
|
||||
* @return A {@link java.util.Collection Collection} containing {@link java.lang.String String} objects
|
||||
* specifying all the object names for this namespace.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error getting the object name list.
|
||||
*/
|
||||
public Collection getNamesForNamespace(String namespace) throws DatabaseException
|
||||
{
|
||||
// call through to the database to get the data for this namespace
|
||||
int nsid = m_nscache.namespaceNameToId(namespace);
|
||||
Map data = m_ops.getAllProperties(m_parent.getMessageID(),m_part,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 UniStorePart
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public long getMessageID()
|
||||
{
|
||||
return m_parent.getMessageID();
|
||||
|
||||
} // end getMessageID
|
||||
|
||||
public int getPartIndex()
|
||||
{
|
||||
return m_part;
|
||||
|
||||
} // end getPartIndex
|
||||
|
||||
public QualifiedNameKey getPartIdentity()
|
||||
{
|
||||
return m_identity;
|
||||
|
||||
} // end getPartIdentity
|
||||
|
||||
public String getMimeType()
|
||||
{
|
||||
return m_mimetype;
|
||||
|
||||
} // end getMimeType
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return m_size;
|
||||
|
||||
} // end getSize
|
||||
|
||||
public int getNumReads()
|
||||
{
|
||||
return m_nread;
|
||||
|
||||
} // end getNumReads
|
||||
|
||||
public java.util.Date getLastReadDate()
|
||||
{
|
||||
return m_lastread;
|
||||
|
||||
} // end getLastReadDate
|
||||
|
||||
public void touchRead() throws DatabaseException
|
||||
{
|
||||
synchronized (this)
|
||||
{ // touch the database, then the local values
|
||||
java.util.Date tmp = m_ops.touchRead(m_parent.getMessageID(),m_part);
|
||||
m_nread++;
|
||||
m_lastread = tmp;
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: post an update?
|
||||
|
||||
} // end touchRead
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface DataItem
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return m_filename;
|
||||
|
||||
} // end getName
|
||||
|
||||
public InputStream getDataStream() throws IOException
|
||||
{
|
||||
try
|
||||
{ // call through to the database to get the data stream
|
||||
return m_ops.getData(m_parent.getMessageID(),m_part);
|
||||
|
||||
} // end try
|
||||
catch (DatabaseException e)
|
||||
{ // create an IOException and chain this one onto it
|
||||
IOException ioe = new IOException("Database error retrieving data stream");
|
||||
ioe.initCause(e);
|
||||
throw ioe;
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end getDataStream
|
||||
|
||||
public Blob getBlob() throws SQLException
|
||||
{
|
||||
try
|
||||
{ // load the data from the database and create the Blob around it
|
||||
byte[] data = new byte[m_size];
|
||||
m_ops.getData(m_parent.getMessageID(),m_part,data);
|
||||
return new ReturnBlob(data);
|
||||
|
||||
} // end try
|
||||
catch (DatabaseException e)
|
||||
{ // create a SQLException and chain this one onto it
|
||||
SQLException se = new SQLException("Database error retrieving data stream");
|
||||
se.initCause(e);
|
||||
throw se;
|
||||
|
||||
} // end catch
|
||||
catch (IOException e)
|
||||
{ // create a SQLException and chain this one onto it
|
||||
SQLException se = new SQLException("I/O error retrieving data stream");
|
||||
se.initCause(e);
|
||||
throw se;
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end getBlob
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface UniStoreBinaryPart
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
} // end class BinaryPartImpl
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import com.silverwrist.util.*;
|
||||
import com.silverwrist.dynamo.db.OpsBase;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
import com.silverwrist.dynamo.util.*;
|
||||
|
||||
abstract class BinaryPartOps extends OpsBase
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected BinaryPartOps(DBConnectionPool pool)
|
||||
{
|
||||
super(pool);
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Abstract operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
abstract Object getProperty(long msgid, int part, PropertyKey key) throws DatabaseException;
|
||||
|
||||
abstract Object setProperty(long msgid, int part, PropertyKey key, Object value) throws DatabaseException;
|
||||
|
||||
abstract Object removeProperty(long msgid, int part, PropertyKey key) throws DatabaseException;
|
||||
|
||||
abstract int[] getPropertyNamespaceIDs(long msgid, int part) throws DatabaseException;
|
||||
|
||||
abstract Map getAllProperties(long msgid, int part, int namespace) throws DatabaseException;
|
||||
|
||||
abstract java.util.Date touchRead(long msgid, int part) throws DatabaseException;
|
||||
|
||||
abstract CacheInputStream getData(long msgid, int part) throws IOException, DatabaseException;
|
||||
|
||||
abstract int getData(long msgid, int part, byte[] here) throws IOException, DatabaseException;
|
||||
|
||||
} // end class BinaryPartOps
|
|
@ -0,0 +1,506 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import com.silverwrist.util.*;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
import com.silverwrist.dynamo.util.*;
|
||||
|
||||
class BinaryPartOps_mysql extends BinaryPartOps
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private PropertySerializer m_psz; // reference to property serializer
|
||||
private DBUtilities m_utils;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
BinaryPartOps_mysql(DBConnectionPool pool)
|
||||
{
|
||||
super(pool);
|
||||
m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class));
|
||||
m_utils = (DBUtilities)(pool.queryService(DBUtilities.class));
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class OpsBase
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
m_psz = null;
|
||||
m_utils = null;
|
||||
super.dispose();
|
||||
|
||||
} // end dispose
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Abstract implementations from class BinaryPartOps
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Object getProperty(long msgid, int part, 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 us_binary_prop WHERE msgid = ? AND part = ? AND nsid = ? "
|
||||
+ "AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,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(BinaryPartOps_mysql.class,"UniStoreMessages","property.deserialize");
|
||||
de.setParameter(0,key.getName());
|
||||
throw de;
|
||||
|
||||
} // end getProperty
|
||||
|
||||
Object setProperty(long msgid, int part, 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(BinaryPartOps_mysql.class,"UniStoreMessages","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;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_binary_prop WRITE;");
|
||||
|
||||
// look to see if the property value is already there
|
||||
stmt = conn.prepareStatement("SELECT prop_value FROM us_binary_prop WHERE msgid = ? AND part = ? AND nsid = ? "
|
||||
+ "AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,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 us_binary_prop SET prop_value = ? WHERE msgid = ? AND part = ? "
|
||||
+ "AND nsid = ? AND prop_name = ?;");
|
||||
stmt.setString(1,serialized_value);
|
||||
stmt.setLong(2,msgid);
|
||||
stmt.setInt(3,part);
|
||||
stmt.setInt(4,key.getNamespaceID());
|
||||
stmt.setString(5,key.getName());
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // prepare the statement to insert a new record
|
||||
stmt = conn.prepareStatement("INSERT INTO us_binary_prop (msgid, part, nsid, prop_name, prop_value) "
|
||||
+ "VALUES (?, ?, ?, ?, ?);");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,key.getName());
|
||||
stmt.setString(5,serialized_value);
|
||||
|
||||
} // end else
|
||||
|
||||
stmt.executeUpdate(); // execute it!
|
||||
|
||||
} // 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 null; // no previous value
|
||||
|
||||
// Deserialize the property value.
|
||||
Object rc = m_psz.deserializeProperty(old_value);
|
||||
if (rc!=null)
|
||||
return rc;
|
||||
|
||||
// deserialization exception - throw it
|
||||
DatabaseException de = new DatabaseException(BinaryPartOps_mysql.class,"UniStoreMessages","property.deserialize");
|
||||
de.setParameter(0,key.getName());
|
||||
throw de;
|
||||
|
||||
} // end setProperty
|
||||
|
||||
Object removeProperty(long msgid, int part, PropertyKey key) throws DatabaseException
|
||||
{
|
||||
String old_value = null;
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
Statement stmt2 = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_binary_prop WRITE;");
|
||||
|
||||
// look to see if the property value is already there
|
||||
stmt = conn.prepareStatement("SELECT prop_value FROM us_binary_prop WHERE msgid = ? AND part = ? AND nsid = ? "
|
||||
+ "AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,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 us_binary_prop WHERE msgid = ? AND part = ? AND nsid = ? "
|
||||
+ "AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,key.getName());
|
||||
stmt.executeUpdate();
|
||||
|
||||
} // 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 rc;
|
||||
|
||||
// deserialization exception - throw it
|
||||
DatabaseException de = new DatabaseException(BinaryPartOps_mysql.class,"UniStoreMessages","property.deserialize");
|
||||
de.setParameter(0,key.getName());
|
||||
throw de;
|
||||
|
||||
} // end removeProperty
|
||||
|
||||
int[] getPropertyNamespaceIDs(long msgid, int part) 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 us_binary_prop WHERE msgid = ? AND part = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
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<tmp.size(); i++)
|
||||
rc[i] = ((Integer)(tmp.get(i))).intValue();
|
||||
tmp.clear();
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end getPropertyNamespaceIDs
|
||||
|
||||
Map getAllProperties(long msgid, int part, int namespace) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// execute the query!
|
||||
stmt = conn.prepareStatement("SELECT prop_name, prop_value FROM us_binary_prop WHERE msgid = ? AND part = ? "
|
||||
+ "AND nsid = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,namespace);
|
||||
rs = stmt.executeQuery();
|
||||
|
||||
// prepare the return value
|
||||
HashMap rc = new HashMap();
|
||||
while (rs.next())
|
||||
{ // copy data out, deserializing properties as we go
|
||||
String key = rs.getString(1);
|
||||
Object value = m_psz.deserializeProperty(rs.getString(2));
|
||||
if (value==null)
|
||||
{ // deserialization exception - throw it
|
||||
DatabaseException de = new DatabaseException(BinaryPartOps_mysql.class,"UniStoreMessages",
|
||||
"property.deserialize");
|
||||
de.setParameter(0,key);
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
rc.put(key,value);
|
||||
|
||||
} // end while
|
||||
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end getAllProperties
|
||||
|
||||
java.util.Date touchRead(long msgid, int part) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
Statement stmt2 = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_binary WRITE;");
|
||||
|
||||
// prepare and execute the statement
|
||||
stmt = conn.prepareStatement("UPDATE us_binary SET reads = reads + 1, lastread = ? WHERE msgid = ? "
|
||||
+ "AND part = ?;");
|
||||
java.util.Date rc = new java.util.Date();
|
||||
m_utils.setDateTime(stmt,1,rc);
|
||||
stmt.setLong(2,msgid);
|
||||
stmt.setInt(3,part);
|
||||
stmt.executeUpdate();
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end touchRead
|
||||
|
||||
CacheInputStream getData(long msgid, int part) throws IOException, DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// create and execute the statement
|
||||
stmt = conn.prepareStatement("SELECT data FROM us_binary WHERE msgid = ? AND part = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setLong(2,part);
|
||||
rs = stmt.executeQuery();
|
||||
if (!(rs.next()))
|
||||
{ // could not find the part
|
||||
DatabaseException de = new DatabaseException(BinaryPartOps_mysql.class,"UniStoreMessages",
|
||||
"bad.loadBinary.part");
|
||||
de.setParameter(0,String.valueOf(part));
|
||||
de.setParameter(1,String.valueOf(msgid));
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
// Create the return value.
|
||||
return new CacheInputStream("bin-" + msgid + "-" + part,rs.getBinaryStream(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
|
||||
|
||||
} // end getData
|
||||
|
||||
int getData(long msgid, int part, byte[] here) throws IOException, DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// create and execute the statement
|
||||
stmt = conn.prepareStatement("SELECT data FROM us_binary WHERE msgid = ? AND part = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setLong(2,part);
|
||||
rs = stmt.executeQuery();
|
||||
if (!(rs.next()))
|
||||
{ // could not find the part
|
||||
DatabaseException de = new DatabaseException(BinaryPartOps_mysql.class,"UniStoreMessages",
|
||||
"bad.loadBinary.part");
|
||||
de.setParameter(0,String.valueOf(part));
|
||||
de.setParameter(1,String.valueOf(msgid));
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
// Copy the return data.
|
||||
InputStream stm = rs.getBinaryStream(1);
|
||||
return stm.read(here);
|
||||
|
||||
} // 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
|
||||
|
||||
} // end getData
|
||||
|
||||
} // end class BinaryPartOps_mysql
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.util.*;
|
||||
import com.silverwrist.dynamo.db.OpsBase;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
|
||||
abstract class ManagerOps extends OpsBase
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static final String PARAM_MSGID = "msgid";
|
||||
static final String PARAM_PARENT = "parent";
|
||||
static final String PARAM_SEQ = "seq";
|
||||
static final String PARAM_CREATOR = "creator";
|
||||
static final String PARAM_POSTED = "posted";
|
||||
static final String PARAM_ACLID = "aclid";
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private MessageOps m_msgops = null;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected ManagerOps(DBConnectionPool pool)
|
||||
{
|
||||
super(pool);
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class OpsBase
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
if (m_msgops!=null)
|
||||
m_msgops.dispose();
|
||||
m_msgops = null;
|
||||
super.dispose();
|
||||
|
||||
} // end dispose
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Abstract operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected abstract MessageOps createMessageOps(DBConnectionPool pool);
|
||||
|
||||
abstract Map getMessageData(long msgid) throws DatabaseException;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
synchronized MessageOps getMessageOps()
|
||||
{
|
||||
if (m_msgops==null)
|
||||
m_msgops = createMessageOps(getPool());
|
||||
return m_msgops;
|
||||
|
||||
} // return getMessageOps
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External static operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static ManagerOps get(DBConnectionPool pool) throws ConfigException
|
||||
{
|
||||
return (ManagerOps)get(pool,ManagerOps.class.getClassLoader(),ManagerOps.class.getName() + "_","ManagerOps");
|
||||
|
||||
} // end get
|
||||
|
||||
} // end class ManagerOps
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import com.silverwrist.util.*;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
|
||||
public class ManagerOps_mysql extends ManagerOps
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private DBUtilities m_utils;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public ManagerOps_mysql(DBConnectionPool pool)
|
||||
{
|
||||
super(pool);
|
||||
m_utils = (DBUtilities)(pool.queryService(DBUtilities.class));
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class ManagerOps
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
m_utils = null;
|
||||
super.dispose();
|
||||
|
||||
} // end dispose
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Abstract implementations from class ManagerOps
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected MessageOps createMessageOps(DBConnectionPool pool)
|
||||
{
|
||||
return new MessageOps_mysql(pool);
|
||||
|
||||
} // end createMessageOps
|
||||
|
||||
Map getMessageData(long msgid) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// prepare and execute a statement to find the header data
|
||||
stmt = conn.prepareStatement("SELECT parent, seq, creator, posted, aclid FROM us_head WHERE msgid = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
rs = stmt.executeQuery();
|
||||
if (!(rs.next()))
|
||||
{ // the message was not found
|
||||
DatabaseException de = new DatabaseException(ManagerOps_mysql.class,"UniStoreMessages","no.message");
|
||||
de.setParameter(0,String.valueOf(msgid));
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
// build the return value
|
||||
HashMap rc = new HashMap();
|
||||
rc.put(PARAM_MSGID,new Long(msgid));
|
||||
rc.put(PARAM_PARENT,new Long(rs.getLong(1)));
|
||||
rc.put(PARAM_SEQ,new Integer(rs.getInt(2)));
|
||||
rc.put(PARAM_CREATOR,new Integer(rs.getInt(3)));
|
||||
rc.put(PARAM_POSTED,m_utils.getDateTime(rs,4));
|
||||
int tmp = rs.getInt(5);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_ACLID,new Integer(tmp));
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end getMessageData
|
||||
|
||||
} // end class ManagerOps_mysql
|
|
@ -0,0 +1,567 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.security.acl.AclNotFoundException;
|
||||
import java.util.*;
|
||||
import org.apache.commons.collections.*;
|
||||
import org.apache.log4j.Logger;
|
||||
import com.silverwrist.dynamo.Namespaces;
|
||||
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.dynamo.util.*;
|
||||
|
||||
class MessageImpl implements UniStoreMessage
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static Logger logger = Logger.getLogger(MessageImpl.class);
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private MessageOps m_ops; // database operations object
|
||||
private NamespaceCache m_nscache; // namespace cache
|
||||
private SecurityReferenceMonitor m_srm; // security reference monitor
|
||||
private UserManagement m_users; // user manager
|
||||
private long m_id; // the message ID
|
||||
private long m_parentid; // the parent message ID
|
||||
private int m_seq; // sequence within parent
|
||||
private int m_creator; // UID of creator
|
||||
private java.util.Date m_posted; // date message was posted
|
||||
private int m_aclid = -1; // ACL id
|
||||
private ReferenceMap m_properties; // properties cache
|
||||
private int m_text_count = -1; // number of text parts
|
||||
private int m_binary_count = -1; // number of binary parts
|
||||
private ReferenceMap m_part_to_text; // mapping from part index to text part
|
||||
private ReferenceMap m_pk_to_text; // mapping from property key to text part
|
||||
private ReferenceMap m_part_to_binary; // mapping from part index to binary part
|
||||
private ReferenceMap m_pk_to_binary; // mapping from property key to binary part
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MessageImpl(MessageOps ops, NamespaceCache nscache, SecurityReferenceMonitor srm, UserManagement users, Map params)
|
||||
{
|
||||
m_ops = ops;
|
||||
m_nscache = nscache;
|
||||
m_srm = srm;
|
||||
m_users = users;
|
||||
m_id = ((Long)(params.get(ManagerOps.PARAM_MSGID))).longValue();
|
||||
m_parentid = ((Long)(params.get(ManagerOps.PARAM_PARENT))).longValue();
|
||||
m_seq = ((Integer)(params.get(ManagerOps.PARAM_SEQ))).intValue();
|
||||
m_creator = ((Integer)(params.get(ManagerOps.PARAM_CREATOR))).intValue();
|
||||
m_posted = (java.util.Date)(params.get(ManagerOps.PARAM_POSTED));
|
||||
Integer tmp = (Integer)(params.get(ManagerOps.PARAM_ACLID));
|
||||
if (tmp!=null)
|
||||
m_aclid = tmp.intValue();
|
||||
m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
|
||||
m_part_to_text = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
|
||||
m_pk_to_text = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
|
||||
m_part_to_binary = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
|
||||
m_pk_to_binary = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface ObjectProvider
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves an object from this <CODE>ObjectProvider</CODE>.
|
||||
*
|
||||
* @param namespace The namespace to interpret the name relative to.
|
||||
* @param name The name of the object to be retrieved.
|
||||
* @return The object reference specified.
|
||||
*/
|
||||
public Object getObject(String namespace, String 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)
|
||||
m_properties.put(key,rc);
|
||||
|
||||
} // end if
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
if (rc==null)
|
||||
throw new NoSuchObjectException(this.toString(),namespace,name);
|
||||
return rc;
|
||||
|
||||
} // end try
|
||||
catch (DatabaseException e)
|
||||
{ // translate into our NoSuchObjectException but retain the DatabaseException
|
||||
throw new NoSuchObjectException(this.toString(),namespace,name,e);
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end getObject
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface SecureObjectStore
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets an object into this message's properties.
|
||||
*
|
||||
* @param caller The user performing the operation.
|
||||
* @param namespace The namespace to interpret the name relative to.
|
||||
* @param name The name of the object to be set.
|
||||
* @param value The object to set into the message's properties.
|
||||
* @return The previous object that was set into the message's properties under this namespace and name, or
|
||||
* <CODE>null</CODE> if there was no such object.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error setting the object value.
|
||||
* @exception com.silverwrist.dynamo.except.DynamoSecurityException If the specified user is not permitted to
|
||||
* set this object value into this message's properties.
|
||||
*/
|
||||
public Object setObject(DynamoUser caller, String namespace, String name, Object value)
|
||||
throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
testPermission(caller,namespace,"set.property","no.setProperty");
|
||||
Object 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);
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name));
|
||||
return rc;
|
||||
|
||||
} // end setObject
|
||||
|
||||
/**
|
||||
* Removes an object from this message's properties.
|
||||
*
|
||||
* @param caller The user performing the operation.
|
||||
* @param namespace The namespace to interpret the name relative to.
|
||||
* @param name The name of the object to be removed.
|
||||
* @return The previous object that was set into the message's properties under this namespace and name, or
|
||||
* <CODE>null</CODE> if there was no such object.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error removing the object value.
|
||||
* @exception com.silverwrist.dynamo.except.DynamoSecurityException If the specified user is not permitted to
|
||||
* remove this object value from this message's properties.
|
||||
*/
|
||||
public Object removeObject(DynamoUser caller, String namespace, String name)
|
||||
throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
testPermission(caller,namespace,"remove.property","no.removeProperty");
|
||||
Object 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);
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name));
|
||||
return rc;
|
||||
|
||||
} // end removeObject
|
||||
|
||||
/**
|
||||
* Returns a collection of all object namespaces that have been set into this message's properties.
|
||||
*
|
||||
* @return A {@link java.util.Collection Collection} containing {@link java.lang.String String} objects specifying
|
||||
* all the object namespaces.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error getting the namespace list.
|
||||
*/
|
||||
public Collection getNamespaces() throws DatabaseException
|
||||
{
|
||||
// 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; i<ids.length; i++)
|
||||
rc.add(m_nscache.namespaceIdToName(ids[i]));
|
||||
return Collections.unmodifiableList(rc);
|
||||
|
||||
} // end getNamespaces
|
||||
|
||||
/**
|
||||
* Returns a collection of all object names that have been set into this message's properties under
|
||||
* a given namespace.
|
||||
*
|
||||
* @param namespace The namespace to look for names under.
|
||||
* @return A {@link java.util.Collection Collection} containing {@link java.lang.String String} objects
|
||||
* specifying all the object names for this namespace.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error getting the object name list.
|
||||
*/
|
||||
public Collection getNamesForNamespace(String namespace) throws DatabaseException
|
||||
{
|
||||
// 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 UniStoreMessage
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public long getMessageID()
|
||||
{
|
||||
return m_id;
|
||||
|
||||
} // end getMessageID
|
||||
|
||||
public long getParentMessageID()
|
||||
{
|
||||
return m_parentid;
|
||||
|
||||
} // end getParentMessageID
|
||||
|
||||
public void setParentMessageID(DynamoUser caller, long id) throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
testPermission(caller,Namespaces.UNISTORE_PERMISSIONS_NAMESPACE,"set.parent","no.setParent");
|
||||
synchronized (this)
|
||||
{ // reset the parent message ID
|
||||
m_ops.setParentMessageID(m_id,id);
|
||||
m_parentid = id;
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: send out an update?
|
||||
|
||||
} // end setParentMessageID
|
||||
|
||||
public int getSequence()
|
||||
{
|
||||
return m_seq;
|
||||
|
||||
} // end getSequence
|
||||
|
||||
public void setSequence(DynamoUser caller, int seq) throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
testPermission(caller,Namespaces.UNISTORE_PERMISSIONS_NAMESPACE,"set.parent","no.setParent");
|
||||
synchronized (this)
|
||||
{ // reset the sequence number
|
||||
m_ops.setSequence(m_id,seq);
|
||||
m_seq = seq;
|
||||
|
||||
} // end if
|
||||
|
||||
// TODO: send out an update?
|
||||
|
||||
} // end setSequence
|
||||
|
||||
public int getCreatorUID()
|
||||
{
|
||||
return m_creator;
|
||||
|
||||
} // end getCreatorUID
|
||||
|
||||
public DynamoUser getCreator() throws DatabaseException
|
||||
{
|
||||
return m_users.getUser(m_creator);
|
||||
|
||||
} // end getCreator
|
||||
|
||||
public java.util.Date getPostDate()
|
||||
{
|
||||
return m_posted;
|
||||
|
||||
} // end getPostDate
|
||||
|
||||
public DynamoAcl getAcl() throws DatabaseException, AclNotFoundException
|
||||
{
|
||||
return m_srm.getAcl(m_aclid);
|
||||
|
||||
} // end getAcl
|
||||
|
||||
public void setAcl(DynamoUser caller, DynamoAcl acl) throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
testPermission(caller,Namespaces.UNISTORE_PERMISSIONS_NAMESPACE,"set.ACL","no.setACL");
|
||||
int aclid = -1;
|
||||
if (acl!=null)
|
||||
aclid = acl.getAclID();
|
||||
synchronized (this)
|
||||
{ // reset the ACL ID
|
||||
m_ops.setAclID(m_id,aclid);
|
||||
m_aclid = aclid;
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: post an update?
|
||||
|
||||
} // end setAcl
|
||||
|
||||
public synchronized int getNumTextParts() throws DatabaseException
|
||||
{
|
||||
if (m_text_count<0)
|
||||
m_text_count = m_ops.getNumTextParts(m_id);
|
||||
return m_text_count;
|
||||
|
||||
} // end getNumTextParts
|
||||
|
||||
public synchronized int getNumBinaryParts() throws DatabaseException
|
||||
{
|
||||
if (m_binary_count<0)
|
||||
m_binary_count = m_ops.getNumBinaryParts(m_id);
|
||||
return m_binary_count;
|
||||
|
||||
} // end getNumBinaryParts
|
||||
|
||||
public UniStoreTextPart getTextPart(int index) throws DatabaseException
|
||||
{
|
||||
Integer key = new Integer(index);
|
||||
TextPartImpl rc = null;
|
||||
synchronized (this)
|
||||
{ // look in the part-to-text map first
|
||||
rc = (TextPartImpl)(m_part_to_text.get(key));
|
||||
if (rc==null)
|
||||
{ // OK, look up the part in the database
|
||||
Map params = m_ops.loadTextPart(m_id,index);
|
||||
PropertyKey otherkey = (PropertyKey)(params.get(MessageOps.PARAM_IDENTITY));
|
||||
rc = (TextPartImpl)(m_pk_to_text.get(otherkey));
|
||||
if (rc==null)
|
||||
{ // need to create a new object
|
||||
rc = new TextPartImpl(m_ops.getTextPartOps(),m_nscache,this,params);
|
||||
m_part_to_text.put(key,rc);
|
||||
m_pk_to_text.put(otherkey,rc);
|
||||
|
||||
} // end if
|
||||
else // feed back into the parts map
|
||||
m_part_to_text.put(key,rc);
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // need to reinsert into property key map
|
||||
QualifiedNameKey qnk = rc.getPartIdentity();
|
||||
PropertyKey pk = new PropertyKey(m_nscache.namespaceNameToId(qnk.getNamespace()),qnk.getName());
|
||||
m_pk_to_text.put(pk,rc);
|
||||
|
||||
} // end else
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
return rc;
|
||||
|
||||
} // end getTextPart
|
||||
|
||||
public UniStoreTextPart getTextPart(String namespace, String name) throws DatabaseException
|
||||
{
|
||||
PropertyKey key = new PropertyKey(m_nscache.namespaceNameToId(namespace),name);
|
||||
TextPartImpl rc = null;
|
||||
synchronized (this)
|
||||
{ // look in the PK-to-text map first
|
||||
rc = (TextPartImpl)(m_pk_to_text.get(key));
|
||||
if (rc==null)
|
||||
{ // OK, look up the part in the database
|
||||
Map params = m_ops.loadTextPart(m_id,key);
|
||||
Integer otherkey = (Integer)(params.get(MessageOps.PARAM_PART));
|
||||
rc = (TextPartImpl)(m_part_to_text.get(otherkey));
|
||||
if (rc==null)
|
||||
{ // OK, need to create the object
|
||||
rc = new TextPartImpl(m_ops.getTextPartOps(),m_nscache,this,params);
|
||||
m_part_to_text.put(otherkey,rc);
|
||||
m_pk_to_text.put(key,rc);
|
||||
|
||||
} // end if
|
||||
else // feed back into the PKs map
|
||||
m_pk_to_text.put(key,rc);
|
||||
|
||||
} // end if
|
||||
else // reinsert into part key map
|
||||
m_part_to_text.put(new Integer(rc.getPartIndex()),rc);
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
return rc;
|
||||
|
||||
} // end getTextPart
|
||||
|
||||
public UniStoreBinaryPart getBinaryPart(int index) throws DatabaseException
|
||||
{
|
||||
Integer key = new Integer(index);
|
||||
BinaryPartImpl rc = null;
|
||||
synchronized (this)
|
||||
{ // look in the part-to-binary map first
|
||||
rc = (BinaryPartImpl)(m_part_to_binary.get(key));
|
||||
if (rc==null)
|
||||
{ // OK, look up the part in the database
|
||||
Map params = m_ops.loadBinaryPart(m_id,index);
|
||||
PropertyKey otherkey = (PropertyKey)(params.get(MessageOps.PARAM_IDENTITY));
|
||||
rc = (BinaryPartImpl)(m_pk_to_binary.get(otherkey));
|
||||
if (rc==null)
|
||||
{ // need to create a new object
|
||||
rc = new BinaryPartImpl(m_ops.getBinaryPartOps(),m_nscache,this,params);
|
||||
m_part_to_binary.put(key,rc);
|
||||
m_pk_to_binary.put(otherkey,rc);
|
||||
|
||||
} // end if
|
||||
else // feed back into the parts map
|
||||
m_part_to_binary.put(key,rc);
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // need to reinsert into property key map
|
||||
QualifiedNameKey qnk = rc.getPartIdentity();
|
||||
PropertyKey pk = new PropertyKey(m_nscache.namespaceNameToId(qnk.getNamespace()),qnk.getName());
|
||||
m_pk_to_binary.put(pk,rc);
|
||||
|
||||
} // end else
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
return rc;
|
||||
|
||||
} // end getBinaryPart
|
||||
|
||||
public UniStoreBinaryPart getBinaryPart(String namespace, String name) throws DatabaseException
|
||||
{
|
||||
PropertyKey key = new PropertyKey(m_nscache.namespaceNameToId(namespace),name);
|
||||
BinaryPartImpl rc = null;
|
||||
synchronized (this)
|
||||
{ // look in the PK-to-binary map first
|
||||
rc = (BinaryPartImpl)(m_pk_to_binary.get(key));
|
||||
if (rc==null)
|
||||
{ // OK, look up the part in the database
|
||||
Map params = m_ops.loadBinaryPart(m_id,key);
|
||||
Integer otherkey = (Integer)(params.get(MessageOps.PARAM_PART));
|
||||
rc = (BinaryPartImpl)(m_part_to_binary.get(otherkey));
|
||||
if (rc==null)
|
||||
{ // OK, need to create the object
|
||||
rc = new BinaryPartImpl(m_ops.getBinaryPartOps(),m_nscache,this,params);
|
||||
m_part_to_binary.put(otherkey,rc);
|
||||
m_pk_to_binary.put(key,rc);
|
||||
|
||||
} // end if
|
||||
else // feed back into the PKs map
|
||||
m_pk_to_binary.put(key,rc);
|
||||
|
||||
} // end if
|
||||
else // reinsert into part key map
|
||||
m_part_to_binary.put(new Integer(rc.getPartIndex()),rc);
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
return rc;
|
||||
|
||||
} // end getBinaryPart
|
||||
|
||||
public List getTextParts() throws DatabaseException
|
||||
{
|
||||
int n = this.getNumTextParts();
|
||||
ArrayList rc = new ArrayList(n);
|
||||
for (int i=1; i<=n; i++)
|
||||
rc.add(this.getTextPart(i));
|
||||
return Collections.unmodifiableList(rc);
|
||||
|
||||
} // end getTextParts
|
||||
|
||||
public List getBinaryParts() throws DatabaseException
|
||||
{
|
||||
int n = this.getNumBinaryParts();
|
||||
ArrayList rc = new ArrayList(n);
|
||||
for (int i=1; i<=n; i++)
|
||||
rc.add(this.getBinaryPart(i));
|
||||
return Collections.unmodifiableList(rc);
|
||||
|
||||
} // end getBinaryParts
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void testPermission(DynamoUser caller, String perm_namespace, String perm_name, String fail_message)
|
||||
throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
if (caller.equals(m_srm.getAdminUser()))
|
||||
return; // Administrator can do anything
|
||||
if (m_aclid==-1)
|
||||
{ // no ACL - rely on fallback method
|
||||
if (caller.getUID()==m_creator)
|
||||
return; // the creator can do anything, but no one else can
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // test against the ACL
|
||||
try
|
||||
{ // look up the ACL
|
||||
if (m_srm.getAcl(m_aclid).testPermission(caller,perm_namespace,perm_name))
|
||||
return;
|
||||
|
||||
} // end try
|
||||
catch (AclNotFoundException e)
|
||||
{ // ACL not found - go to fallback mechanism
|
||||
logger.warn("ACL " + m_aclid + " not found while testing message " + m_id);
|
||||
if (caller.getUID()==m_creator)
|
||||
return; // the creator can do anything, but no one else can
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end else
|
||||
|
||||
// Throw a DynamoSecurityException indicating what you're not permitted to do.
|
||||
DynamoSecurityException de = new DynamoSecurityException(MessageImpl.class,"UniStoreMessages",fail_message);
|
||||
de.setParameter(0,String.valueOf(m_id));
|
||||
throw de;
|
||||
|
||||
} // end testPermission
|
||||
|
||||
} // end class MessageImpl
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
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 MessageOps extends OpsBase
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static final String PARAM_PART = "part";
|
||||
static final String PARAM_IDENTITY = "identity";
|
||||
static final String PARAM_MIMETYPE = "mimetype";
|
||||
static final String PARAM_SIZE = "size";
|
||||
static final String PARAM_LINECOUNT = "linecount";
|
||||
static final String PARAM_READS = "reads";
|
||||
static final String PARAM_LASTREAD = "lastread";
|
||||
static final String PARAM_FILENAME = "filename";
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private TextPartOps m_textops = null;
|
||||
private BinaryPartOps m_binaryops = null;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected MessageOps(DBConnectionPool pool)
|
||||
{
|
||||
super(pool);
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class OpsBase
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
if (m_textops!=null)
|
||||
m_textops.dispose();
|
||||
m_textops = null;
|
||||
if (m_binaryops!=null)
|
||||
m_binaryops.dispose();
|
||||
m_binaryops = null;
|
||||
super.dispose();
|
||||
|
||||
} // end dispose
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Abstract operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected abstract TextPartOps createTextPartOps(DBConnectionPool pool);
|
||||
|
||||
protected abstract BinaryPartOps createBinaryPartOps(DBConnectionPool pool);
|
||||
|
||||
abstract Object getProperty(long msgid, PropertyKey key) throws DatabaseException;
|
||||
|
||||
abstract Object setProperty(long msgid, PropertyKey key, Object value) throws DatabaseException;
|
||||
|
||||
abstract Object removeProperty(long msgid, PropertyKey key) throws DatabaseException;
|
||||
|
||||
abstract int[] getPropertyNamespaceIDs(long msgid) throws DatabaseException;
|
||||
|
||||
abstract Map getAllProperties(long msgid, int namespace) throws DatabaseException;
|
||||
|
||||
abstract void setParentMessageID(long msgid, long parent) throws DatabaseException;
|
||||
|
||||
abstract void setSequence(long msgid, int seq) throws DatabaseException;
|
||||
|
||||
abstract void setAclID(long msgid, int aclid) throws DatabaseException;
|
||||
|
||||
abstract int getNumTextParts(long msgid) throws DatabaseException;
|
||||
|
||||
abstract int getNumBinaryParts(long msgid) throws DatabaseException;
|
||||
|
||||
abstract Map loadTextPart(long msgid, int part) throws DatabaseException;
|
||||
|
||||
abstract Map loadTextPart(long msgid, PropertyKey identity) throws DatabaseException;
|
||||
|
||||
abstract Map loadBinaryPart(long msgid, int part) throws DatabaseException;
|
||||
|
||||
abstract Map loadBinaryPart(long msgid, PropertyKey identity) throws DatabaseException;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* External operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
synchronized TextPartOps getTextPartOps()
|
||||
{
|
||||
if (m_textops==null)
|
||||
m_textops = createTextPartOps(getPool());
|
||||
return m_textops;
|
||||
|
||||
} // end getTextPartOps
|
||||
|
||||
synchronized BinaryPartOps getBinaryPartOps()
|
||||
{
|
||||
if (m_binaryops==null)
|
||||
m_binaryops = createBinaryPartOps(getPool());
|
||||
return m_binaryops;
|
||||
|
||||
} // end getBinaryPartOps
|
||||
|
||||
} // end class MessageOps
|
|
@ -0,0 +1,793 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import com.silverwrist.util.*;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
import com.silverwrist.dynamo.util.*;
|
||||
|
||||
class MessageOps_mysql extends MessageOps
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private PropertySerializer m_psz; // reference to property serializer
|
||||
private DBUtilities m_utils;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MessageOps_mysql(DBConnectionPool pool)
|
||||
{
|
||||
super(pool);
|
||||
m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class));
|
||||
m_utils = (DBUtilities)(pool.queryService(DBUtilities.class));
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class MessageOps
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
m_psz = null;
|
||||
m_utils = null;
|
||||
super.dispose();
|
||||
|
||||
} // end dispose
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Abstract operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected TextPartOps createTextPartOps(DBConnectionPool pool)
|
||||
{
|
||||
return new TextPartOps_mysql(pool);
|
||||
|
||||
} // end createTextPartOps
|
||||
|
||||
protected BinaryPartOps createBinaryPartOps(DBConnectionPool pool)
|
||||
{
|
||||
return new BinaryPartOps_mysql(pool);
|
||||
|
||||
} // end createBinaryPartOps
|
||||
|
||||
Object getProperty(long msgid, 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 us_prop WHERE msgid = ? AND nsid = ? AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
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(MessageOps_mysql.class,"UniStoreMessages","property.deserialize");
|
||||
de.setParameter(0,key.getName());
|
||||
throw de;
|
||||
|
||||
} // end getProperty
|
||||
|
||||
Object setProperty(long msgid, 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(MessageOps_mysql.class,"UniStoreMessages","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;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_prop WRITE;");
|
||||
|
||||
// look to see if the property value is already there
|
||||
stmt = conn.prepareStatement("SELECT prop_value FROM us_prop WHERE msgid = ? AND nsid = ? AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
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 us_prop SET prop_value = ? WHERE msgid = ? AND nsid = ? "
|
||||
+ "AND prop_name = ?;");
|
||||
stmt.setString(1,serialized_value);
|
||||
stmt.setLong(2,msgid);
|
||||
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 us_prop (msgid, nsid, prop_name, prop_value) VALUES (?, ?, ?, ?);");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,key.getNamespaceID());
|
||||
stmt.setString(3,key.getName());
|
||||
stmt.setString(4,serialized_value);
|
||||
|
||||
} // end else
|
||||
|
||||
stmt.executeUpdate(); // execute it!
|
||||
|
||||
} // 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 null; // no previous value
|
||||
|
||||
// Deserialize the property value.
|
||||
Object rc = m_psz.deserializeProperty(old_value);
|
||||
if (rc!=null)
|
||||
return rc;
|
||||
|
||||
// deserialization exception - throw it
|
||||
DatabaseException de = new DatabaseException(MessageOps_mysql.class,"UniStoreMessages","property.deserialize");
|
||||
de.setParameter(0,key.getName());
|
||||
throw de;
|
||||
|
||||
} // end setProperty
|
||||
|
||||
Object removeProperty(long msgid, PropertyKey key) throws DatabaseException
|
||||
{
|
||||
String old_value = null;
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
Statement stmt2 = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_prop WRITE;");
|
||||
|
||||
// look to see if the property value is already there
|
||||
stmt = conn.prepareStatement("SELECT prop_value FROM us_prop WHERE msgid = ? AND nsid = ? AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
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 us_prop WHERE msgid = ? AND nsid = ? AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,key.getNamespaceID());
|
||||
stmt.setString(3,key.getName());
|
||||
stmt.executeUpdate();
|
||||
|
||||
} // 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 rc;
|
||||
|
||||
// deserialization exception - throw it
|
||||
DatabaseException de = new DatabaseException(MessageOps_mysql.class,"UniStoreMessages","property.deserialize");
|
||||
de.setParameter(0,key.getName());
|
||||
throw de;
|
||||
|
||||
} // end removeProperty
|
||||
|
||||
int[] getPropertyNamespaceIDs(long msgid) 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 us_prop WHERE msgid = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
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<tmp.size(); i++)
|
||||
rc[i] = ((Integer)(tmp.get(i))).intValue();
|
||||
tmp.clear();
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end getPropertyNamespaceIDs
|
||||
|
||||
Map getAllProperties(long msgid, int namespace) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// execute the query!
|
||||
stmt = conn.prepareStatement("SELECT prop_name, prop_value FROM us_prop WHERE msgid = ? AND nsid = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,namespace);
|
||||
rs = stmt.executeQuery();
|
||||
|
||||
// prepare the return value
|
||||
HashMap rc = new HashMap();
|
||||
while (rs.next())
|
||||
{ // copy data out, deserializing properties as we go
|
||||
String key = rs.getString(1);
|
||||
Object value = m_psz.deserializeProperty(rs.getString(2));
|
||||
if (value==null)
|
||||
{ // deserialization exception - throw it
|
||||
DatabaseException de = new DatabaseException(MessageOps_mysql.class,"UniStoreMessages",
|
||||
"property.deserialize");
|
||||
de.setParameter(0,key);
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
rc.put(key,value);
|
||||
|
||||
} // end while
|
||||
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end getAllProperties
|
||||
|
||||
void setParentMessageID(long msgid, long parent) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
Statement stmt2 = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_head WRITE;");
|
||||
|
||||
// update the parent field
|
||||
stmt = conn.prepareStatement("UPDATE us_head SET parent = ? WHERE msgid = ?;");
|
||||
stmt.setLong(1,parent);
|
||||
stmt.setLong(2,msgid);
|
||||
stmt.executeUpdate();
|
||||
|
||||
} // 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
|
||||
|
||||
} // end try
|
||||
|
||||
void setSequence(long msgid, int seq) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
Statement stmt2 = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_head WRITE;");
|
||||
|
||||
// update the sequence field
|
||||
stmt = conn.prepareStatement("UPDATE us_head SET seq = ? WHERE msgid = ?;");
|
||||
stmt.setInt(1,seq);
|
||||
stmt.setLong(2,msgid);
|
||||
stmt.executeUpdate();
|
||||
|
||||
} // 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
|
||||
|
||||
} // end setSequence
|
||||
|
||||
void setAclID(long msgid, int aclid) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
Statement stmt2 = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_head WRITE;");
|
||||
|
||||
// update the ACL ID field
|
||||
stmt = conn.prepareStatement("UPDATE us_head SET aclid = ? WHERE msgid = ?;");
|
||||
if (aclid<=0)
|
||||
stmt.setNull(1,Types.INTEGER);
|
||||
else
|
||||
stmt.setInt(1,aclid);
|
||||
stmt.setLong(2,msgid);
|
||||
stmt.executeUpdate();
|
||||
|
||||
} // 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
|
||||
|
||||
} // end setAclID
|
||||
|
||||
int getNumTextParts(long msgid) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// create and execute the statement
|
||||
stmt = conn.prepareStatement("SELECT COUNT(*) FROM us_text WHERE msgid = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
rs = stmt.executeQuery();
|
||||
return SQLUtils.getReturnCountInt(rs,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
|
||||
|
||||
} // end getNumTextParts
|
||||
|
||||
int getNumBinaryParts(long msgid) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// create and execute the statement
|
||||
stmt = conn.prepareStatement("SELECT COUNT(*) FROM us_binary WHERE msgid = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
rs = stmt.executeQuery();
|
||||
return SQLUtils.getReturnCountInt(rs,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
|
||||
|
||||
} // end getNumBinaryParts
|
||||
|
||||
Map loadTextPart(long msgid, int part) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// create and execute the statement
|
||||
stmt = conn.prepareStatement("SELECT ident_nsid, ident_name, mimetype, charcount, linecount, reads, last_read "
|
||||
+ "FROM us_text WHERE msgid = ? AND part = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
rs = stmt.executeQuery();
|
||||
if (!(rs.next()))
|
||||
{ // could not find the part
|
||||
DatabaseException de = new DatabaseException(MessageOps_mysql.class,"UniStoreMessages","bad.loadText.part");
|
||||
de.setParameter(0,String.valueOf(part));
|
||||
de.setParameter(1,String.valueOf(msgid));
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
// Prepare the return value.
|
||||
HashMap rc = new HashMap();
|
||||
rc.put(PARAM_PART,new Integer(part));
|
||||
rc.put(PARAM_IDENTITY,new PropertyKey(rs.getInt(1),rs.getString(2)));
|
||||
String s = rs.getString(3);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_MIMETYPE,s);
|
||||
int tmp = rs.getInt(4);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_SIZE,new Integer(tmp));
|
||||
tmp = rs.getInt(5);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_LINECOUNT,new Integer(tmp));
|
||||
rc.put(PARAM_READS,new Integer(rs.getInt(6)));
|
||||
java.util.Date dt = m_utils.getDateTime(rs,7);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_LASTREAD,dt);
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end loadTextPart
|
||||
|
||||
Map loadTextPart(long msgid, PropertyKey identity) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// create and execute the statement
|
||||
stmt = conn.prepareStatement("SELECT part, mimetype, charcount, linecount, reads, last_read "
|
||||
+ "FROM us_text WHERE msgid = ? AND ident_nsid = ? AND ident_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,identity.getNamespaceID());
|
||||
stmt.setString(3,identity.getName());
|
||||
rs = stmt.executeQuery();
|
||||
if (!(rs.next()))
|
||||
{ // could not find the part
|
||||
DatabaseException de = new DatabaseException(MessageOps_mysql.class,"UniStoreMessages","bad.loadText.id");
|
||||
de.setParameter(0,String.valueOf(identity.getNamespaceID()));
|
||||
de.setParameter(1,identity.getName());
|
||||
de.setParameter(2,String.valueOf(msgid));
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
// Prepare the return value.
|
||||
HashMap rc = new HashMap();
|
||||
rc.put(PARAM_PART,new Integer(rs.getInt(1)));
|
||||
rc.put(PARAM_IDENTITY,identity);
|
||||
String s = rs.getString(2);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_MIMETYPE,s);
|
||||
int tmp = rs.getInt(3);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_SIZE,new Integer(tmp));
|
||||
tmp = rs.getInt(4);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_LINECOUNT,new Integer(tmp));
|
||||
rc.put(PARAM_READS,new Integer(rs.getInt(5)));
|
||||
java.util.Date dt = m_utils.getDateTime(rs,6);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_LASTREAD,dt);
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end loadTextPart
|
||||
|
||||
Map loadBinaryPart(long msgid, int part) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// create and execute the statement
|
||||
stmt = conn.prepareStatement("SELECT ident_nsid, ident_name, mimetype, datalen, filename, reads, last_read "
|
||||
+ "FROM us_binary WHERE msgid = ? AND part = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
rs = stmt.executeQuery();
|
||||
if (!(rs.next()))
|
||||
{ // could not find the part
|
||||
DatabaseException de = new DatabaseException(MessageOps_mysql.class,"UniStoreMessages","bad.loadBinary.part");
|
||||
de.setParameter(0,String.valueOf(part));
|
||||
de.setParameter(1,String.valueOf(msgid));
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
// Prepare the return value.
|
||||
HashMap rc = new HashMap();
|
||||
rc.put(PARAM_PART,new Integer(part));
|
||||
rc.put(PARAM_IDENTITY,new PropertyKey(rs.getInt(1),rs.getString(2)));
|
||||
String s = rs.getString(3);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_MIMETYPE,s);
|
||||
int tmp = rs.getInt(4);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_SIZE,new Integer(tmp));
|
||||
s = rs.getString(5);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_FILENAME,s);
|
||||
rc.put(PARAM_READS,new Integer(rs.getInt(6)));
|
||||
java.util.Date dt = m_utils.getDateTime(rs,7);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_LASTREAD,dt);
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end loadBinaryPart
|
||||
|
||||
Map loadBinaryPart(long msgid, PropertyKey identity) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// create and execute the statement
|
||||
stmt = conn.prepareStatement("SELECT part, mimetype, datalen, filename, reads, last_read "
|
||||
+ "FROM us_binary WHERE msgid = ? AND ident_nsid = ? AND ident_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,identity.getNamespaceID());
|
||||
stmt.setString(3,identity.getName());
|
||||
rs = stmt.executeQuery();
|
||||
if (!(rs.next()))
|
||||
{ // could not find the part
|
||||
DatabaseException de = new DatabaseException(MessageOps_mysql.class,"UniStoreMessages","bad.loadBinary.id");
|
||||
de.setParameter(0,String.valueOf(identity.getNamespaceID()));
|
||||
de.setParameter(1,identity.getName());
|
||||
de.setParameter(2,String.valueOf(msgid));
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
// Prepare the return value.
|
||||
HashMap rc = new HashMap();
|
||||
rc.put(PARAM_PART,new Integer(rs.getInt(1)));
|
||||
rc.put(PARAM_IDENTITY,identity);
|
||||
String s = rs.getString(2);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_MIMETYPE,s);
|
||||
int tmp = rs.getInt(3);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_SIZE,new Integer(tmp));
|
||||
s = rs.getString(4);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_FILENAME,s);
|
||||
rc.put(PARAM_READS,new Integer(rs.getInt(5)));
|
||||
java.util.Date dt = m_utils.getDateTime(rs,6);
|
||||
if (!(rs.wasNull()))
|
||||
rc.put(PARAM_LASTREAD,dt);
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end loadBinaryPart
|
||||
|
||||
} // end class MessageOps_mysql
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.ref.*;
|
||||
import java.util.*;
|
||||
import org.apache.commons.collections.*;
|
||||
import com.silverwrist.dynamo.db.NamespaceCache;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
import com.silverwrist.dynamo.util.*;
|
||||
|
||||
class TextPartImpl implements UniStoreTextPart
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private TextPartOps m_ops;
|
||||
private NamespaceCache m_nscache;
|
||||
private MessageImpl m_parent;
|
||||
private int m_part;
|
||||
private QualifiedNameKey m_identity;
|
||||
private String m_mimetype;
|
||||
private int m_size;
|
||||
private int m_linecount;
|
||||
private int m_nread;
|
||||
private java.util.Date m_lastread;
|
||||
private ReferenceMap m_properties;
|
||||
private SoftReference m_text = null;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
TextPartImpl(TextPartOps ops, NamespaceCache nscache, MessageImpl parent, Map params) throws DatabaseException
|
||||
{
|
||||
m_ops = ops;
|
||||
m_nscache = nscache;
|
||||
m_parent = parent;
|
||||
m_part = ((Integer)(params.get(MessageOps.PARAM_PART))).intValue();
|
||||
PropertyKey pk = (PropertyKey)(params.get(MessageOps.PARAM_IDENTITY));
|
||||
m_identity = new QualifiedNameKey(nscache.namespaceIdToName(pk.getNamespaceID()),pk.getName());
|
||||
m_mimetype = (String)(params.get(MessageOps.PARAM_MIMETYPE));
|
||||
Integer tmp = (Integer)(params.get(MessageOps.PARAM_SIZE));
|
||||
if (tmp!=null)
|
||||
m_size = tmp.intValue();
|
||||
tmp = (Integer)(params.get(MessageOps.PARAM_LINECOUNT));
|
||||
if (tmp!=null)
|
||||
m_linecount = tmp.intValue();
|
||||
m_nread = ((Integer)(params.get(MessageOps.PARAM_READS))).intValue();
|
||||
m_lastread = (java.util.Date)(params.get(MessageOps.PARAM_LASTREAD));
|
||||
m_properties = new ReferenceMap(ReferenceMap.HARD,ReferenceMap.SOFT);
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface ObjectProvider
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves an object from this <CODE>ObjectProvider</CODE>.
|
||||
*
|
||||
* @param namespace The namespace to interpret the name relative to.
|
||||
* @param name The name of the object to be retrieved.
|
||||
* @return The object reference specified.
|
||||
*/
|
||||
public Object getObject(String namespace, String 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_parent.getMessageID(),m_part,key);
|
||||
if (rc!=null)
|
||||
m_properties.put(key,rc);
|
||||
|
||||
} // end if
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
if (rc==null)
|
||||
throw new NoSuchObjectException(this.toString(),namespace,name);
|
||||
return rc;
|
||||
|
||||
} // end try
|
||||
catch (DatabaseException e)
|
||||
{ // translate into our NoSuchObjectException but retain the DatabaseException
|
||||
throw new NoSuchObjectException(this.toString(),namespace,name,e);
|
||||
|
||||
} // end catch
|
||||
|
||||
} // end getObject
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface SecureObjectStore
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets an object into this <CODE>SecureObjectStore</CODE>.
|
||||
*
|
||||
* @param caller The user performing the operation.
|
||||
* @param namespace The namespace to interpret the name relative to.
|
||||
* @param name The name of the object to be set.
|
||||
* @param value The object to set into the <CODE>SecureObjectStore</CODE>.
|
||||
* @return The previous object that was set into the <CODE>SecureObjectStore</CODE> under this namespace and name, or
|
||||
* <CODE>null</CODE> if there was no such object.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error setting the object value.
|
||||
* @exception com.silverwrist.dynamo.except.DynamoSecurityException If the specified user is not permitted to
|
||||
* set this object value into this <CODE>SecureObjectStore</CODE>.
|
||||
*/
|
||||
public Object setObject(DynamoUser caller, String namespace, String name, Object value)
|
||||
throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
m_parent.testPermission(caller,namespace,"set.property","no.setProperty");
|
||||
Object 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_parent.getMessageID(),m_part,key,value);
|
||||
|
||||
// and cache it, too
|
||||
m_properties.put(key,value);
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name));
|
||||
return rc;
|
||||
|
||||
} // end setObject
|
||||
|
||||
/**
|
||||
* Removes an object from this <CODE>SecureObjectStore</CODE>.
|
||||
*
|
||||
* @param caller The user performing the operation.
|
||||
* @param namespace The namespace to interpret the name relative to.
|
||||
* @param name The name of the object to be removed.
|
||||
* @return The previous object that was set into the <CODE>SecureObjectStore</CODE> under this namespace and name, or
|
||||
* <CODE>null</CODE> if there was no such object.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error removing the object value.
|
||||
* @exception com.silverwrist.dynamo.except.DynamoSecurityException If the specified user is not permitted to
|
||||
* remove this object value from this <CODE>SecureObjectStore</CODE>.
|
||||
*/
|
||||
public Object removeObject(DynamoUser caller, String namespace, String name)
|
||||
throws DatabaseException, DynamoSecurityException
|
||||
{
|
||||
m_parent.testPermission(caller,namespace,"remove.property","no.removeProperty");
|
||||
Object 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_parent.getMessageID(),m_part,key);
|
||||
|
||||
// and remove the cached value, too
|
||||
m_properties.remove(key);
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: m_post.postUpdate(new GlobalPropertyUpdateEvent(this,namespace,name));
|
||||
return rc;
|
||||
|
||||
} // end removeObject
|
||||
|
||||
/**
|
||||
* Returns a collection of all object namespaces that have been set into this <CODE>SecureObjectStore</CODE>.
|
||||
*
|
||||
* @return A {@link java.util.Collection Collection} containing {@link java.lang.String String} objects specifying
|
||||
* all the object namespaces.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error getting the namespace list.
|
||||
*/
|
||||
public Collection getNamespaces() throws DatabaseException
|
||||
{
|
||||
// call through to the database to get the list of namespace IDs
|
||||
int[] ids = m_ops.getPropertyNamespaceIDs(m_parent.getMessageID(),m_part);
|
||||
|
||||
ArrayList rc = new ArrayList(ids.length);
|
||||
for (int i=0; i<ids.length; i++)
|
||||
rc.add(m_nscache.namespaceIdToName(ids[i]));
|
||||
return Collections.unmodifiableList(rc);
|
||||
|
||||
} // end getNamespaces
|
||||
|
||||
/**
|
||||
* Returns a collection of all object names that have been set into this <CODE>SecureObjectStore</CODE> under
|
||||
* a given namespace.
|
||||
*
|
||||
* @param namespace The namespace to look for names under.
|
||||
* @return A {@link java.util.Collection Collection} containing {@link java.lang.String String} objects
|
||||
* specifying all the object names for this namespace.
|
||||
* @exception com.silverwrist.dynamo.except.DatabaseException If there was an error getting the object name list.
|
||||
*/
|
||||
public Collection getNamesForNamespace(String namespace) throws DatabaseException
|
||||
{
|
||||
// call through to the database to get the data for this namespace
|
||||
int nsid = m_nscache.namespaceNameToId(namespace);
|
||||
Map data = m_ops.getAllProperties(m_parent.getMessageID(),m_part,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 UniStorePart
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public long getMessageID()
|
||||
{
|
||||
return m_parent.getMessageID();
|
||||
|
||||
} // end getMessageID
|
||||
|
||||
public int getPartIndex()
|
||||
{
|
||||
return m_part;
|
||||
|
||||
} // end getPartIndex
|
||||
|
||||
public QualifiedNameKey getPartIdentity()
|
||||
{
|
||||
return m_identity;
|
||||
|
||||
} // end getPartIdentity
|
||||
|
||||
public String getMimeType()
|
||||
{
|
||||
return m_mimetype;
|
||||
|
||||
} // end getMimeType
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return m_size;
|
||||
|
||||
} // end getSize
|
||||
|
||||
public int getNumReads()
|
||||
{
|
||||
return m_nread;
|
||||
|
||||
} // end getNumReads
|
||||
|
||||
public java.util.Date getLastReadDate()
|
||||
{
|
||||
return m_lastread;
|
||||
|
||||
} // end getLastReadDate
|
||||
|
||||
public void touchRead() throws DatabaseException
|
||||
{
|
||||
synchronized (this)
|
||||
{ // touch the database, then the local values
|
||||
java.util.Date tmp = m_ops.touchRead(m_parent.getMessageID(),m_part);
|
||||
m_nread++;
|
||||
m_lastread = tmp;
|
||||
|
||||
} // end synchronized block
|
||||
|
||||
// TODO: post an update?
|
||||
|
||||
} // end touchRead
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface UniStoreTextPart
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public int getLineCount()
|
||||
{
|
||||
return m_linecount;
|
||||
|
||||
} // end getLineCount
|
||||
|
||||
public synchronized String getText() throws DatabaseException
|
||||
{
|
||||
String rc = null;
|
||||
if (m_text!=null)
|
||||
rc = (String)(m_text.get());
|
||||
if (rc==null)
|
||||
{ // load text fom database and reload to reference
|
||||
rc = m_ops.getText(m_parent.getMessageID(),m_part);
|
||||
m_text = new SoftReference(rc);
|
||||
|
||||
} // end if
|
||||
|
||||
return rc;
|
||||
|
||||
} // end getText
|
||||
|
||||
public Reader getTextAsReader() throws DatabaseException
|
||||
{
|
||||
return new StringReader(this.getText());
|
||||
|
||||
} // end getTextAsReader
|
||||
|
||||
} // end class TextPartImpl
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
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 TextPartOps extends OpsBase
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
protected TextPartOps(DBConnectionPool pool)
|
||||
{
|
||||
super(pool);
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Abstract operations
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
abstract Object getProperty(long msgid, int part, PropertyKey key) throws DatabaseException;
|
||||
|
||||
abstract Object setProperty(long msgid, int part, PropertyKey key, Object value) throws DatabaseException;
|
||||
|
||||
abstract Object removeProperty(long msgid, int part, PropertyKey key) throws DatabaseException;
|
||||
|
||||
abstract int[] getPropertyNamespaceIDs(long msgid, int part) throws DatabaseException;
|
||||
|
||||
abstract Map getAllProperties(long msgid, int part, int namespace) throws DatabaseException;
|
||||
|
||||
abstract java.util.Date touchRead(long msgid, int part) throws DatabaseException;
|
||||
|
||||
abstract String getText(long msgid, int part) throws DatabaseException;
|
||||
|
||||
} // end class TextPartOps
|
|
@ -0,0 +1,458 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import com.silverwrist.util.*;
|
||||
import com.silverwrist.dynamo.except.*;
|
||||
import com.silverwrist.dynamo.iface.*;
|
||||
import com.silverwrist.dynamo.util.*;
|
||||
|
||||
class TextPartOps_mysql extends TextPartOps
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private PropertySerializer m_psz; // reference to property serializer
|
||||
private DBUtilities m_utils;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
TextPartOps_mysql(DBConnectionPool pool)
|
||||
{
|
||||
super(pool);
|
||||
m_psz = (PropertySerializer)(pool.queryService(PropertySerializer.class));
|
||||
m_utils = (DBUtilities)(pool.queryService(DBUtilities.class));
|
||||
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Overrides from class OpsBase
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
m_psz = null;
|
||||
m_utils = null;
|
||||
super.dispose();
|
||||
|
||||
} // end dispose
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Abstract implementations from class TextPartOps
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Object getProperty(long msgid, int part, 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 us_text_prop WHERE msgid = ? AND part = ? AND nsid = ? "
|
||||
+ "AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,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(TextPartOps_mysql.class,"UniStoreMessages","property.deserialize");
|
||||
de.setParameter(0,key.getName());
|
||||
throw de;
|
||||
|
||||
} // end getProperty
|
||||
|
||||
Object setProperty(long msgid, int part, 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(TextPartOps_mysql.class,"UniStoreMessages","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;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_text_prop WRITE;");
|
||||
|
||||
// look to see if the property value is already there
|
||||
stmt = conn.prepareStatement("SELECT prop_value FROM us_text_prop WHERE msgid = ? AND part = ? AND nsid = ? "
|
||||
+ "AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,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 us_text_prop SET prop_value = ? WHERE msgid = ? AND part = ? "
|
||||
+ "AND nsid = ? AND prop_name = ?;");
|
||||
stmt.setString(1,serialized_value);
|
||||
stmt.setLong(2,msgid);
|
||||
stmt.setInt(3,part);
|
||||
stmt.setInt(4,key.getNamespaceID());
|
||||
stmt.setString(5,key.getName());
|
||||
|
||||
} // end if
|
||||
else
|
||||
{ // prepare the statement to insert a new record
|
||||
stmt = conn.prepareStatement("INSERT INTO us_text_prop (msgid, part, nsid, prop_name, prop_value) "
|
||||
+ "VALUES (?, ?, ?, ?, ?);");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,key.getName());
|
||||
stmt.setString(5,serialized_value);
|
||||
|
||||
} // end else
|
||||
|
||||
stmt.executeUpdate(); // execute it!
|
||||
|
||||
} // 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 null; // no previous value
|
||||
|
||||
// Deserialize the property value.
|
||||
Object rc = m_psz.deserializeProperty(old_value);
|
||||
if (rc!=null)
|
||||
return rc;
|
||||
|
||||
// deserialization exception - throw it
|
||||
DatabaseException de = new DatabaseException(TextPartOps_mysql.class,"UniStoreMessages","property.deserialize");
|
||||
de.setParameter(0,key.getName());
|
||||
throw de;
|
||||
|
||||
} // end setProperty
|
||||
|
||||
Object removeProperty(long msgid, int part, PropertyKey key) throws DatabaseException
|
||||
{
|
||||
String old_value = null;
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
Statement stmt2 = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_text_prop WRITE;");
|
||||
|
||||
// look to see if the property value is already there
|
||||
stmt = conn.prepareStatement("SELECT prop_value FROM us_text_prop WHERE msgid = ? AND part = ? AND nsid = ? "
|
||||
+ "AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,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 us_text_prop WHERE msgid = ? AND part = ? AND nsid = ? "
|
||||
+ "AND prop_name = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,key.getNamespaceID());
|
||||
stmt.setString(4,key.getName());
|
||||
stmt.executeUpdate();
|
||||
|
||||
} // 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 rc;
|
||||
|
||||
// deserialization exception - throw it
|
||||
DatabaseException de = new DatabaseException(TextPartOps_mysql.class,"UniStoreMessages","property.deserialize");
|
||||
de.setParameter(0,key.getName());
|
||||
throw de;
|
||||
|
||||
} // end removeProperty
|
||||
|
||||
int[] getPropertyNamespaceIDs(long msgid, int part) 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 us_text_prop WHERE msgid = ? AND part = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
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<tmp.size(); i++)
|
||||
rc[i] = ((Integer)(tmp.get(i))).intValue();
|
||||
tmp.clear();
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end getPropertyNamespaceIDs
|
||||
|
||||
Map getAllProperties(long msgid, int part, int namespace) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// execute the query!
|
||||
stmt = conn.prepareStatement("SELECT prop_name, prop_value FROM us_text_prop WHERE msgid = ? AND part = ? "
|
||||
+ "AND nsid = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
stmt.setInt(3,namespace);
|
||||
rs = stmt.executeQuery();
|
||||
|
||||
// prepare the return value
|
||||
HashMap rc = new HashMap();
|
||||
while (rs.next())
|
||||
{ // copy data out, deserializing properties as we go
|
||||
String key = rs.getString(1);
|
||||
Object value = m_psz.deserializeProperty(rs.getString(2));
|
||||
if (value==null)
|
||||
{ // deserialization exception - throw it
|
||||
DatabaseException de = new DatabaseException(TextPartOps_mysql.class,"UniStoreMessages",
|
||||
"property.deserialize");
|
||||
de.setParameter(0,key);
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
rc.put(key,value);
|
||||
|
||||
} // end while
|
||||
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end getAllProperties
|
||||
|
||||
java.util.Date touchRead(long msgid, int part) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
Statement stmt2 = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// lock the table
|
||||
stmt2 = conn.createStatement();
|
||||
stmt2.executeUpdate("LOCK TABLES us_text WRITE;");
|
||||
|
||||
// prepare and execute the statement
|
||||
stmt = conn.prepareStatement("UPDATE us_text SET reads = reads + 1, lastread = ? WHERE msgid = ? AND part = ?;");
|
||||
java.util.Date rc = new java.util.Date();
|
||||
m_utils.setDateTime(stmt,1,rc);
|
||||
stmt.setLong(2,msgid);
|
||||
stmt.setInt(3,part);
|
||||
stmt.executeUpdate();
|
||||
return rc;
|
||||
|
||||
} // 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
|
||||
|
||||
} // end touchRead
|
||||
|
||||
String getText(long msgid, int part) throws DatabaseException
|
||||
{
|
||||
Connection conn = null;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
try
|
||||
{ // get a connection
|
||||
conn = getConnection();
|
||||
|
||||
// create and execute the statement
|
||||
stmt = conn.prepareStatement("SELECT data FROM us_text WHERE msgid = ? AND part = ?;");
|
||||
stmt.setLong(1,msgid);
|
||||
stmt.setInt(2,part);
|
||||
rs = stmt.executeQuery();
|
||||
if (!(rs.next()))
|
||||
{ // could not find the part
|
||||
DatabaseException de = new DatabaseException(TextPartOps_mysql.class,"UniStoreMessages","bad.loadText.part");
|
||||
de.setParameter(0,String.valueOf(part));
|
||||
de.setParameter(1,String.valueOf(msgid));
|
||||
throw de;
|
||||
|
||||
} // end if
|
||||
|
||||
return 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
|
||||
|
||||
} // end getText
|
||||
|
||||
} // end class TextPartOps_mysql
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
* (the "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Venice Web Communities System.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
package com.silverwrist.dynamo.unistore;
|
||||
|
||||
import java.util.*;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.w3c.dom.*;
|
||||
import com.silverwrist.util.*;
|
||||
import com.silverwrist.util.xml.*;
|
||||
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.dynamo.util.*;
|
||||
|
||||
public class UniStoreManager implements NamedObject, ComponentInitialize, ComponentShutdown, UniStore
|
||||
{
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Static data members
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private static Logger logger = Logger.getLogger(UniStoreManager.class);
|
||||
|
||||
private static int DEFAULT_MSGCACHE_HARD = 100;
|
||||
private static int DEFAULT_MSGCACHE_SOFT = 1000;
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Attributes
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
private String m_name; // name of this object
|
||||
private NamespaceCache m_ns_cache; // namespace cache object
|
||||
private ManagerOps m_ops; // database operations object
|
||||
private SecurityReferenceMonitor m_srm; // security reference monitor
|
||||
private UserManagement m_users; // user management object
|
||||
private HardSoftCache m_msgcache; // message cache
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Constructor
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public UniStoreManager()
|
||||
{ // do nothing
|
||||
} // end constructor
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface NamedObject
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return m_name;
|
||||
|
||||
} // end getName
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface ComponentInitialize
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialize the component.
|
||||
*
|
||||
* @param config_root Pointer to the section of the Dynamo XML configuration file that configures this
|
||||
* particular component. This is to be considered "read-only" by the component.
|
||||
* @param services An implementation of {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider}
|
||||
* which provides initialization services to the component. This will include an implementation
|
||||
* of {@link com.silverwrist.dynamo.iface.ObjectProvider ObjectProvider} which may be used to
|
||||
* get information about other objects previously initialized by the application.
|
||||
* @exception com.silverwrist.dynamo.except.ConfigException If an error is encountered in the component
|
||||
* configuration.
|
||||
*/
|
||||
public void initialize(Element config_root, ServiceProvider services) throws ConfigException
|
||||
{
|
||||
logger.info("UniStoreManager initializing");
|
||||
XMLLoader loader = XMLLoader.get();
|
||||
String conn_name = null;
|
||||
String nscache_name = null;
|
||||
String srm_name = null;
|
||||
String users_name = null;
|
||||
int msgcache_hard = DEFAULT_MSGCACHE_HARD, msgcache_soft = DEFAULT_MSGCACHE_SOFT;
|
||||
try
|
||||
{ // verify the right node name
|
||||
loader.verifyNodeName(config_root,"object");
|
||||
|
||||
// get the object's name
|
||||
m_name = loader.getAttribute(config_root,"name");
|
||||
|
||||
// get the database configuration connection
|
||||
DOMElementHelper config_root_h = new DOMElementHelper(config_root);
|
||||
Element elt = loader.getSubElement(config_root_h,"database");
|
||||
conn_name = loader.getAttribute(elt,"connection");
|
||||
nscache_name = loader.getAttribute(elt,"namespaces");
|
||||
|
||||
// get the security reference monitor name
|
||||
elt = loader.getSubElement(config_root_h,"security");
|
||||
srm_name = loader.getAttribute(elt,"object");
|
||||
|
||||
// get the user management object name
|
||||
elt = loader.getSubElement(config_root_h,"user-manager");
|
||||
users_name = loader.getAttribute(elt,"object");
|
||||
|
||||
// get the message cache configuration
|
||||
elt = config_root_h.getSubElement("message-cache");
|
||||
if (elt!=null)
|
||||
{ // load the limits
|
||||
msgcache_hard = loader.getAttributeInt(elt,"hardlimit",DEFAULT_MSGCACHE_HARD);
|
||||
msgcache_soft = loader.getAttributeInt(elt,"softlimit",DEFAULT_MSGCACHE_SOFT);
|
||||
|
||||
} // end if
|
||||
|
||||
} // end try
|
||||
catch (XMLLoadException e)
|
||||
{ // error loading XML config data
|
||||
throw new ConfigException(e);
|
||||
|
||||
} // end catch
|
||||
|
||||
// Create the message cache.
|
||||
m_msgcache = new HardSoftCache(msgcache_hard,msgcache_soft);
|
||||
|
||||
// Get the database connection pool and namespace cache.
|
||||
DBConnectionPool pool = GetObjectUtils.getDatabaseConnection(services,conn_name);
|
||||
m_ns_cache =
|
||||
(NamespaceCache)(GetObjectUtils.getDynamoComponent(services,NamespaceCache.class,nscache_name));
|
||||
|
||||
// Get the operations object.
|
||||
m_ops = ManagerOps.get(pool);
|
||||
|
||||
// Get the security reference monitor and user manager object..
|
||||
m_srm = (SecurityReferenceMonitor)(GetObjectUtils.getDynamoComponent(services,SecurityReferenceMonitor.class,
|
||||
srm_name));
|
||||
m_users = (UserManagement)(GetObjectUtils.getDynamoComponent(services,UserManagement.class,users_name));
|
||||
|
||||
} // end initialize
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface ComponentShutdown
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public void shutdown()
|
||||
{
|
||||
m_msgcache.clear();
|
||||
m_srm = null;
|
||||
m_users = null;
|
||||
m_ns_cache = null;
|
||||
m_ops.dispose();
|
||||
m_ops = null;
|
||||
|
||||
} // end shutdown
|
||||
|
||||
/*--------------------------------------------------------------------------------
|
||||
* Implementations from interface UniStore
|
||||
*--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
public synchronized UniStoreMessage getMessage(long msgid) throws DatabaseException
|
||||
{
|
||||
Long key = new Long(msgid);
|
||||
MessageImpl rc = (MessageImpl)(m_msgcache.get(key));
|
||||
if (rc==null)
|
||||
{ // need to look it up in the database!
|
||||
Map params = m_ops.getMessageData(msgid);
|
||||
rc = new MessageImpl(m_ops.getMessageOps(),m_ns_cache,m_srm,m_users,params);
|
||||
params.clear();
|
||||
m_msgcache.put(key,rc);
|
||||
|
||||
} // end if
|
||||
|
||||
return rc;
|
||||
|
||||
} // end getMessage
|
||||
|
||||
} // end class UniStoreManager
|
|
@ -0,0 +1,28 @@
|
|||
# The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
# (the "License"); you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
||||
# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
||||
# language governing rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Venice Web Communities System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
|
||||
# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
||||
# Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# ---------------------------------------------------------------------------------
|
||||
# This file has been localized for the en_US locale
|
||||
no.message=Unable to find the message with ID #{0} in the Universal Message Store.
|
||||
property.serialize=The value of property "{0}" could not be serialized.
|
||||
property.deserialize=The value of property "{0}" could not be deserialized.
|
||||
no.setProperty=You are not authorized to set properties on message #{0}.
|
||||
no.removeProperty=You are not authorized to remove properties from message #{0}.
|
||||
no.setParent=You are not authorized to change the parent message information of message #{0}.
|
||||
no.setACL=You are not authorized to change the access control list of message #{0}.
|
||||
bad.loadText.part=Unable to find text part #{0} of message #{1} in the Universal Message Store.
|
||||
bad.loadText.id=Unable to find text part with ID {0}::{1} in message #{2} in the Universal Message Store.
|
||||
bad.loadBinary.part=Unable to find binary part #{0} of message #{1} in the Universal Message Store.
|
||||
bad.loadBinary.id=Unable to find binary part with ID {0}::{1} in message #{2} in the Universal Message Store.
|
Loading…
Reference in New Issue
Block a user