339 lines
12 KiB
Java
339 lines
12 KiB
Java
/*
|
|
* 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
|