diff --git a/config/alfresco/avm-base-context.xml b/config/alfresco/avm-base-context.xml
index 30a504ba80..2d4b07ce91 100644
--- a/config/alfresco/avm-base-context.xml
+++ b/config/alfresco/avm-base-context.xml
@@ -109,12 +109,6 @@
-
-
-
-
-
-
@@ -194,6 +188,9 @@
+
+
+
diff --git a/config/alfresco/avm-services-context.xml b/config/alfresco/avm-services-context.xml
index fe3e5ecbad..c5db7dd4ea 100644
--- a/config/alfresco/avm-services-context.xml
+++ b/config/alfresco/avm-services-context.xml
@@ -16,16 +16,6 @@
-
-
- content
-
-
-
-
-
-
@@ -64,12 +54,6 @@
-
-
-
-
-
-
@@ -125,9 +109,6 @@
-
-
-
@@ -217,9 +198,6 @@
-
-
-
diff --git a/config/alfresco/content-services-context.xml b/config/alfresco/content-services-context.xml
index 57634868a1..9c7a9847fa 100644
--- a/config/alfresco/content-services-context.xml
+++ b/config/alfresco/content-services-context.xml
@@ -66,6 +66,9 @@
+
+
+
diff --git a/config/alfresco/model/contentModel.xml b/config/alfresco/model/contentModel.xml
index 06ea1289ff..f45e1b43d7 100644
--- a/config/alfresco/model/contentModel.xml
+++ b/config/alfresco/model/contentModel.xml
@@ -81,6 +81,10 @@
true
+
+ d:boolean
+ false
+
diff --git a/config/alfresco/node-services-context.xml b/config/alfresco/node-services-context.xml
index d1c98514ea..af5fcd6233 100644
--- a/config/alfresco/node-services-context.xml
+++ b/config/alfresco/node-services-context.xml
@@ -15,6 +15,7 @@
@@ -58,6 +59,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/source/java/org/alfresco/model/ContentModel.java b/source/java/org/alfresco/model/ContentModel.java
index c40491691e..928898b10d 100644
--- a/source/java/org/alfresco/model/ContentModel.java
+++ b/source/java/org/alfresco/model/ContentModel.java
@@ -92,6 +92,7 @@ public interface ContentModel
// content type and aspect constants
static final QName TYPE_CONTENT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "content");
static final QName PROP_CONTENT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "content");
+ static final QName PROP_READONLY = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "readonly");
// title aspect
static final QName ASPECT_TITLED = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "titled");
diff --git a/source/java/org/alfresco/repo/avm/AVMContext.java b/source/java/org/alfresco/repo/avm/AVMContext.java
index 4e088608b5..9b4f7df4f5 100644
--- a/source/java/org/alfresco/repo/avm/AVMContext.java
+++ b/source/java/org/alfresco/repo/avm/AVMContext.java
@@ -3,12 +3,18 @@
*/
package org.alfresco.repo.avm;
+import org.alfresco.repo.content.ContentStore;
+import org.alfresco.service.cmr.repository.ContentService;
+import org.alfresco.service.cmr.repository.MimetypeService;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
/**
* This is the (shudder) global context for AVM. It a rendezvous
* point for access to needed global instances.
* @author britt
*/
-class AVMContext
+class AVMContext implements ApplicationContextAware
{
/**
* The single instance of an AVMContext.
@@ -40,11 +46,6 @@ class AVMContext
*/
public VersionRootDAO fVersionRootDAO;
- /**
- * The FileContentDAO.
- */
- public FileContentDAO fFileContentDAO;
-
/**
* The ChildEntryDAO.
*/
@@ -80,6 +81,36 @@ class AVMContext
*/
public AVMStorePropertyDAO fAVMStorePropertyDAO;
+ /**
+ * The ContentService.
+ */
+ private ContentService fContentService;
+
+ /**
+ * The Mimetype Service.
+ */
+ private MimetypeService fMimetypeService;
+
+ /**
+ * The AVMService.
+ */
+ private AVMService fAVMService;
+
+ /**
+ * The Content Store.
+ */
+ private ContentStore fContentStore;
+
+ /**
+ * The application context.
+ */
+ public ApplicationContext fAppContext;
+
+ public void setApplicationContext(ApplicationContext context)
+ {
+ fAppContext = context;
+ }
+
/**
* @param nodeDAO the fAVMNodeDAO to set
*/
@@ -104,14 +135,6 @@ class AVMContext
fDeletedChildDAO = deletedChildDAO;
}
- /**
- * @param fileContentDAO the fFileContentDAO to set
- */
- public void setFileContentDAO(FileContentDAO fileContentDAO)
- {
- fFileContentDAO = fileContentDAO;
- }
-
/**
* @param historyLinkDAO the fHistoryLinkDAO to set
*/
@@ -169,4 +192,56 @@ class AVMContext
{
fAVMStorePropertyDAO = avmStorePropertyDAO;
}
+
+ /**
+ * Get the Content Service.
+ * @return The ContentService object.
+ */
+ public ContentService getContentService()
+ {
+ if (fContentService == null)
+ {
+ fContentService = (ContentService)fAppContext.getBean("contentService");
+ }
+ return fContentService;
+ }
+
+ /**
+ * Get the mime type service.
+ * @return The mime type service.
+ */
+ public MimetypeService getMimetypeService()
+ {
+ if (fMimetypeService == null)
+ {
+ fMimetypeService = (MimetypeService)fAppContext.getBean("mimetypeService");
+ }
+ return fMimetypeService;
+ }
+
+ /**
+ * Get the AVM Service.
+ * @return The AVMService instance.
+ */
+ public AVMService getAVMService()
+ {
+ if (fAVMService == null)
+ {
+ fAVMService = (AVMService)fAppContext.getBean("AVMService");
+ }
+ return fAVMService;
+ }
+
+ /**
+ * Get the ContentStore.
+ * @return The content store.
+ */
+ public ContentStore getContentStore()
+ {
+ if (fContentStore == null)
+ {
+ fContentStore = (ContentStore)fAppContext.getBean("fileContentStore");
+ }
+ return fContentStore;
+ }
}
diff --git a/source/java/org/alfresco/repo/avm/AVMCrawler.java b/source/java/org/alfresco/repo/avm/AVMCrawler.java
index 0883844373..a52e6f1c29 100644
--- a/source/java/org/alfresco/repo/avm/AVMCrawler.java
+++ b/source/java/org/alfresco/repo/avm/AVMCrawler.java
@@ -216,8 +216,7 @@ class AVMCrawler implements Runnable
}
catch (Exception e)
{
- if (e instanceof AVMNotFoundException ||
- e instanceof AVMExistsException)
+ if (e instanceof AVMException)
{
return;
}
diff --git a/source/java/org/alfresco/repo/avm/AVMInterpreter.java b/source/java/org/alfresco/repo/avm/AVMInterpreter.java
index 085e9c7ed1..830861f587 100644
--- a/source/java/org/alfresco/repo/avm/AVMInterpreter.java
+++ b/source/java/org/alfresco/repo/avm/AVMInterpreter.java
@@ -375,6 +375,7 @@ public class AVMInterpreter
out.println("Mod Time: " + new Date(desc.getModDate()));
}
}
+ /*
else if (command[0].equals("catver"))
{
if (command.length != 4)
@@ -398,6 +399,7 @@ public class AVMInterpreter
}
reader.close();
}
+ */
else if (command[0].equals("ca"))
{
if (command.length != 5)
diff --git a/source/java/org/alfresco/repo/avm/AVMNodeConverter.java b/source/java/org/alfresco/repo/avm/AVMNodeConverter.java
index b10936c45d..4a5bf9fc43 100644
--- a/source/java/org/alfresco/repo/avm/AVMNodeConverter.java
+++ b/source/java/org/alfresco/repo/avm/AVMNodeConverter.java
@@ -25,7 +25,7 @@ import org.alfresco.service.cmr.repository.StoreRef;
* the StoreRef
, NodeRef
world.
* @author britt
*/
-class AVMNodeConverter
+public class AVMNodeConverter
{
/**
* Get a NodeRef corresponding to the given path and version.
diff --git a/source/java/org/alfresco/repo/avm/AVMNodeService.java b/source/java/org/alfresco/repo/avm/AVMNodeService.java
index 1f66f1b9de..b5b480436c 100644
--- a/source/java/org/alfresco/repo/avm/AVMNodeService.java
+++ b/source/java/org/alfresco/repo/avm/AVMNodeService.java
@@ -27,8 +27,6 @@ import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
-import javax.naming.OperationNotSupportedException;
-
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.Auditable;
@@ -39,6 +37,7 @@ import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.AssociationExistsException;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.CyclicChildRelationshipException;
import org.alfresco.service.cmr.repository.InvalidChildAssociationRefException;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
@@ -80,6 +79,15 @@ public class AVMNodeService implements NodeService
fAVMService = service;
}
+ /**
+ * Set the DictionaryService. For Spring.
+ * @param dictionaryService The DictionaryService instance.
+ */
+ public void setDictionaryService(DictionaryService dictionaryService)
+ {
+ fDictionaryService = dictionaryService;
+ }
+
/**
* Default constructor.
*/
@@ -281,6 +289,10 @@ public class AVMNodeService implements NodeService
Map props = new HashMap();
for (QName qname : properties.keySet())
{
+ if (isBuiltInProperty(qname))
+ {
+ continue;
+ }
props.put(qname, new PropertyValue(null, properties.get(qname)));
}
fAVMService.setNodeProperties(newAVMPath, props);
@@ -645,6 +657,19 @@ public class AVMNodeService implements NodeService
result.put(ContentModel.PROP_MODIFIED, new Date(desc.getModDate()));
result.put(ContentModel.PROP_MODIFIER, desc.getLastModifier());
result.put(ContentModel.PROP_OWNER, desc.getOwner());
+ if (desc.isFile())
+ {
+ try
+ {
+ ContentData contentData = fAVMService.getContentDataForRead((Integer)avmVersionPath[0],
+ (String)avmVersionPath[1]);
+ result.put(ContentModel.PROP_CONTENT, contentData);
+ }
+ catch (AVMException e)
+ {
+ // TODO For now ignore.
+ }
+ }
return result;
}
@@ -690,6 +715,21 @@ public class AVMNodeService implements NodeService
QName qName,
NodeRef nodeRef)
{
+ if (qName.equals(ContentModel.PROP_CONTENT))
+ {
+ try
+ {
+ ContentData contentData =
+ fAVMService.getContentDataForRead((Integer)avmVersionPath[0],
+ (String)avmVersionPath[1]);
+ return contentData;
+ }
+ catch (AVMException e)
+ {
+ // TODO For now, ignore.
+ return null;
+ }
+ }
AVMNodeDescriptor desc = null;
try
{
@@ -778,7 +818,8 @@ public class AVMNodeService implements NodeService
qName.equals(ContentModel.PROP_CREATOR) ||
qName.equals(ContentModel.PROP_MODIFIED) ||
qName.equals(ContentModel.PROP_MODIFIER) ||
- qName.equals(ContentModel.PROP_OWNER);
+ qName.equals(ContentModel.PROP_OWNER) ||
+ qName.equals(ContentModel.PROP_CONTENT);
}
/**
@@ -795,12 +836,15 @@ public class AVMNodeService implements NodeService
*/
public void setProperty(NodeRef nodeRef, QName qname, Serializable value) throws InvalidNodeRefException
{
+ Object [] avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
// TODO Just until we can set built in properties on AVM Nodes.
if (isBuiltInProperty(qname))
{
+ if (qname.equals(ContentModel.PROP_CONTENT))
+ {
+ }
return;
}
- Object [] avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
if ((Integer)avmVersionPath[0] >= 0)
{
throw new InvalidNodeRefException("Read only store.", nodeRef);
diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java
index 066ad220b5..359f6f510e 100644
--- a/source/java/org/alfresco/repo/avm/AVMRepository.java
+++ b/source/java/org/alfresco/repo/avm/AVMRepository.java
@@ -20,7 +20,6 @@ package org.alfresco.repo.avm;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -28,6 +27,10 @@ import java.util.Map;
import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue;
+import org.alfresco.service.cmr.repository.ContentData;
+import org.alfresco.service.cmr.repository.ContentReader;
+import org.alfresco.service.cmr.repository.ContentService;
+import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.namespace.QName;
/**
@@ -52,11 +55,6 @@ class AVMRepository
*/
private Issuer fNodeIssuer;
- /**
- * The content id issuer;
- */
- private Issuer fContentIssuer;
-
/**
* The layer id issuer.
*/
@@ -94,15 +92,6 @@ class AVMRepository
fNodeIssuer = nodeIssuer;
}
- /**
- * Set the content issuer. For Spring.
- * @param contentIssuer The issuer.
- */
- public void setContentIssuer(Issuer contentIssuer)
- {
- fContentIssuer = contentIssuer;
- }
-
/**
* Set the layer issuer. For Spring.
* @param layerIssuer The issuer.
@@ -281,21 +270,6 @@ class AVMRepository
return rep.getOutputStream(pathParts[1]);
}
- /**
- * Get a random access file from a file node.
- * @param version The version id (read-only if not -1)
- * @param path The path to the file.
- * @param access The access mode for RandomAccessFile.
- * @return A RandomAccessFile.
- */
- public RandomAccessFile getRandomAccess(int version, String path, String access)
- {
- fLookupCount.set(1);
- String[] pathParts = SplitPath(path);
- AVMStore rep = getAVMStoreByName(pathParts[0]);
- return rep.getRandomAccess(version, pathParts[1], access);
- }
-
/**
* Rename a node.
* @param srcPath Source containing directory.
@@ -524,25 +498,30 @@ class AVMRepository
}
/**
- * Get an InputStream from a given version of a file.
- * @param desc The node descriptor.
- * @return The InputStream.
+ * Get a ContentReader from a file.
+ * @param version The version to look under.
+ * @param path The path to the file.
+ * @return A ContentReader
*/
- public InputStream getInputStream(AVMNodeDescriptor desc)
+ public ContentReader getReader(int version, String path)
{
fLookupCount.set(1);
- AVMNode node = AVMContext.fgInstance.fAVMNodeDAO.getByID(desc.getId());
- if (node == null)
- {
- throw new AVMNotFoundException("Not found.");
- }
- if (node.getType() != AVMNodeType.PLAIN_FILE &&
- node.getType() != AVMNodeType.LAYERED_FILE)
- {
- throw new AVMWrongTypeException("Not a file.");
- }
- FileNode file = (FileNode)node;
- return file.getContentForRead().getInputStream();
+ String [] pathParts = SplitPath(path);
+ AVMStore store = getAVMStoreByName(pathParts[0]);
+ return store.getReader(version, pathParts[1]);
+ }
+
+ /**
+ * Get a ContentWriter to a file.
+ * @param path The path to the file.
+ * @return A ContentWriter.
+ */
+ public ContentWriter getWriter(String path)
+ {
+ fLookupCount.set(1);
+ String [] pathParts = SplitPath(path);
+ AVMStore store = getAVMStoreByName(pathParts[0]);
+ return store.getWriter(pathParts[1]);
}
/**
@@ -666,15 +645,6 @@ class AVMRepository
return fNodeIssuer.issue();
}
- /**
- * Issue a content id.
- * @return The new id.
- */
- public long issueContentID()
- {
- return fContentIssuer.issue();
- }
-
/**
* Issue a new layer id.
* @return The new id.
@@ -1112,6 +1082,46 @@ class AVMRepository
return null;
}
+ /**
+ * Get the ContentData for a file.
+ * @param version The version to look under.
+ * @param path The path to the file.
+ * @return The ContentData for the file.
+ */
+ public ContentData getContentDataForRead(int version, String path)
+ {
+ fLookupCount.set(1);
+ String [] pathParts = SplitPath(path);
+ AVMStore store = getAVMStoreByName(pathParts[0]);
+ return store.getContentDataForRead(version, pathParts[1]);
+ }
+
+ /**
+ * Get the ContentData for a file for writing.
+ * @param path The path to the file.
+ * @return The ContentData object.
+ */
+ public ContentData getContentDataForWrite(String path)
+ {
+ fLookupCount.set(1);
+ String [] pathParts = SplitPath(path);
+ AVMStore store = getAVMStoreByName(pathParts[0]);
+ return store.getContentDataForWrite(pathParts[1]);
+ }
+
+ /**
+ * Set the ContentData on a file.
+ * @param path The path to the file.
+ * @param data The content data to set.
+ */
+ public void setContentData(String path, ContentData data)
+ {
+ fLookupCount.set(1);
+ String [] pathParts = SplitPath(path);
+ AVMStore store = getAVMStoreByName(pathParts[0]);
+ store.setContentData(pathParts[1], data);
+ }
+
/**
* Get the single instance of AVMRepository.
* @return The single instance.
diff --git a/source/java/org/alfresco/repo/avm/AVMService.java b/source/java/org/alfresco/repo/avm/AVMService.java
index 92be632dcc..8add9bd427 100644
--- a/source/java/org/alfresco/repo/avm/AVMService.java
+++ b/source/java/org/alfresco/repo/avm/AVMService.java
@@ -19,13 +19,15 @@ package org.alfresco.repo.avm;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.RandomAccessFile;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue;
+import org.alfresco.service.cmr.repository.ContentData;
+import org.alfresco.service.cmr.repository.ContentReader;
+import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.namespace.QName;
/**
@@ -49,15 +51,6 @@ public interface AVMService
*/
public InputStream getFileInputStream(int version, String path);
- /**
- * Get an input stream from a particular version of a file.
- * @param desc The node descriptor pointing at the node.
- * @return The InputStream.
- * @throws AVMNotFoundException If desc
is dangling or
- * otherwise invalid.
- */
- public InputStream getFileInputStream(AVMNodeDescriptor desc);
-
/**
* Get an output stream to a file node. The file must already exist.
* @param path The simple absolute path to the file node.
@@ -68,18 +61,23 @@ public interface AVMService
public OutputStream getFileOutputStream(String path);
/**
- * Get a random access file to the given path.
- * @param version The version to find.
+ * Get a ContentReader for the given file.
+ * @param version The version to look under.
* @param path The path to the file.
- * @param access The access mode for RandomAccessFile.
- * @return A RandomAccessFile
- * @throws AVMNotFoundException If path
is not found.
- * @throws AVMWrongTypeException If path
contains a non-terminal
- * component that is not a directory, or if path
is not pointing
- * at a file.
- * @throws AVMException If trying to write to anything but the head version.
+ * @return A ContentReader.
+ * @throws AVMNotFoundException If path
does not exist.
+ * @throws AVMWrongTypeException if path
is not a file.
*/
- public RandomAccessFile getRandomAccess(int version, String path, String access);
+ public ContentReader getReader(int version, String path);
+
+ /**
+ * Get a ContentWriter to a file.
+ * @param path The path to the file.
+ * @return A ContentWriter.
+ * @throws AVMNotFoundException If path
does not exist.
+ * @throws AVMWrongTypeException if path
is not a file.
+ */
+ public ContentWriter getWriter(String path);
/**
* Get a listing of a Folder by name.
@@ -545,4 +543,35 @@ public interface AVMService
* does not exist.
*/
public void deleteStoreProperty(String store, QName name);
+
+ /**
+ * Get the ContentData for a node. Only applies to a file.
+ * @param version The version to look under.
+ * @param path The path to the node.
+ * @return The ContentData object.
+ * @throws AVMNotFoundException If path
does not exist.
+ * @throws AVMWrongTypeException If path
does not
+ * point to a file.
+ */
+ public ContentData getContentDataForRead(int version, String path);
+
+ /**
+ * Get the ContentData for a node.
+ * @param path The path to the node.
+ * @return The ContentData object.
+ * @throws AVMNotFoundException If path
does not exist.
+ * @throws AVMWrongTypeException If path
does not point
+ * to a file.
+ */
+ public ContentData getContentDataForWrite(String path);
+
+ /**
+ * Set the content data on a file.
+ * @param path The path to the file.
+ * @param data The ContentData to set.
+ * @throws AVMNotFoundException If path
does not exist.
+ * @throws AVMWrongTypeException If path
does not point
+ * to a file.
+ */
+ public void setContentData(String path, ContentData data);
}
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java
index d84a6d90df..cef93322c9 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java
@@ -30,6 +30,9 @@ import java.util.SortedMap;
import org.alfresco.repo.avm.AVMRepository;
import org.alfresco.repo.domain.PropertyValue;
+import org.alfresco.service.cmr.repository.ContentData;
+import org.alfresco.service.cmr.repository.ContentReader;
+import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.namespace.QName;
import org.apache.log4j.Logger;
@@ -152,30 +155,57 @@ class AVMServiceImpl implements AVMService
}
/**
- * Get an InputStream from a particular version of a file.
- * @param desc The node descriptor.
- * @return The InputStream.
+ * Get a ContentReader for the given file.
+ * @param version The version to look under.
+ * @param path The path to the file.
+ * @return A ContentReader.
*/
- public InputStream getFileInputStream(final AVMNodeDescriptor desc)
+ public ContentReader getReader(final int version, final String path)
{
- if (desc == null)
+ if (path == null)
{
- throw new AVMBadArgumentException("Illegal null argument.");
+ throw new AVMBadArgumentException("Null path.");
}
class TxnCallback implements RetryingTransactionCallback
{
- public InputStream in = null;
+ public ContentReader reader;
public void perform()
{
- in = fAVMRepository.getInputStream(desc);
+ reader = fAVMRepository.getReader(version, path);
}
}
TxnCallback doit = new TxnCallback();
fTransaction.perform(doit, false);
- return doit.in;
+ return doit.reader;
}
+ /**
+ * Get a ContentWriter to a file.
+ * @param path The path to the file.
+ * @return A ContentWriter.
+ * @throws AVMNotFoundException If path
does not exist.
+ * @throws AVMWrongTypeException if path
is not a file.
+ */
+ public ContentWriter getWriter(final String path)
+ {
+ if (path == null)
+ {
+ throw new AVMBadArgumentException("Null path.");
+ }
+ class TxnCallback implements RetryingTransactionCallback
+ {
+ public ContentWriter writer;
+
+ public void perform()
+ {
+ writer = fAVMRepository.getWriter(path);
+ }
+ }
+ TxnCallback doit = new TxnCallback();
+ fTransaction.perform(doit, true);
+ return doit.writer;
+ }
/**
* Get an output stream to a file. Triggers versioning.
*/
@@ -199,34 +229,6 @@ class AVMServiceImpl implements AVMService
return doit.out;
}
- /**
- * Get a random access file to the given file.
- * @param version The version to look for (read-only)
- * @param path The path to the file.
- * @param access The access mode for RandomAccessFile
- * @return A Random Access File.
- */
- public RandomAccessFile getRandomAccess(final int version, final String path, final String access)
- {
- if (path == null || access == null)
- {
- throw new AVMBadArgumentException("Illegal null argument.");
- }
- class TxnCallback implements RetryingTransactionCallback
- {
- public RandomAccessFile file;
-
- public void perform()
- {
- file = fAVMRepository.getRandomAccess(version, path, access);
- }
- }
- TxnCallback doit = new TxnCallback();
- fTransaction.perform(doit, true);
- return doit.file;
- }
-
-
/**
* Get a directory listing.
* @param version The version id to lookup.
@@ -1322,4 +1324,80 @@ class AVMServiceImpl implements AVMService
TxnCallback doit = new TxnCallback();
fTransaction.perform(doit, true);
}
+
+ /**
+ * Get the ContentData for a node. Only applies to a file.
+ * @param version The version to look under.
+ * @param path The path to the node.
+ * @return The ContentData object.
+ */
+ public ContentData getContentDataForRead(final int version, final String path)
+ {
+ if (path == null)
+ {
+ throw new AVMBadArgumentException("Null Path.");
+ }
+ class TxnCallback implements RetryingTransactionCallback
+ {
+ public ContentData content;
+
+ public void perform()
+ {
+ content = fAVMRepository.getContentDataForRead(version, path);
+ }
+ }
+ TxnCallback doit = new TxnCallback();
+ fTransaction.perform(doit, false);
+ return doit.content;
+ }
+
+ /**
+ * Get the Content data for writing.
+ * @param path The path to the node.
+ * @return The ContentData object.
+ */
+ public ContentData getContentDataForWrite(final String path)
+ {
+ if (path == null)
+ {
+ throw new AVMBadArgumentException("Null Path.");
+ }
+ class TxnCallback implements RetryingTransactionCallback
+ {
+ public ContentData content;
+
+ public void perform()
+ {
+ content = fAVMRepository.getContentDataForWrite(path);
+ }
+ }
+ TxnCallback doit = new TxnCallback();
+ fTransaction.perform(doit, true);
+ return doit.content;
+ }
+
+ /**
+ * Set the content data on a file.
+ * @param path The path to the file.
+ * @param data The ContentData to set.
+ * @throws AVMNotFoundException If path
does not exist.
+ * @throws AVMWrongTypeException If path
does not point
+ * to a file.
+ */
+ public void setContentData(final String path, final ContentData data)
+ {
+ if (path == null || data == null)
+ {
+ throw new AVMBadArgumentException("Null Path.");
+ }
+ class TxnCallback implements RetryingTransactionCallback
+ {
+ public void perform()
+ {
+ fAVMRepository.setContentData(path, data);
+ }
+ }
+ TxnCallback doit = new TxnCallback();
+ fTransaction.perform(doit, true);
+ }
}
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
index 7692d97784..67e2bb6e6b 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
@@ -1890,6 +1890,7 @@ public class AVMServiceTest extends AVMServiceTestBase
/**
* The random access.
*/
+ /*
public void testRandomAccess()
{
try
@@ -1914,6 +1915,7 @@ public class AVMServiceTest extends AVMServiceTestBase
fail();
}
}
+ */
/**
* Test COW during long operations.
diff --git a/source/java/org/alfresco/repo/avm/AVMStore.java b/source/java/org/alfresco/repo/avm/AVMStore.java
index 3591863abb..748cad54f0 100644
--- a/source/java/org/alfresco/repo/avm/AVMStore.java
+++ b/source/java/org/alfresco/repo/avm/AVMStore.java
@@ -19,13 +19,15 @@ package org.alfresco.repo.avm;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.RandomAccessFile;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import org.alfresco.repo.domain.PropertyValue;
+import org.alfresco.service.cmr.repository.ContentData;
+import org.alfresco.service.cmr.repository.ContentReader;
+import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.namespace.QName;
/**
@@ -102,7 +104,22 @@ interface AVMStore
* @return An InputStream
*/
public InputStream getInputStream(int version, String path);
+
+ /**
+ * Get a ContentReader from a file.
+ * @param version The version to look under.
+ * @param path The path to the file.
+ * @return A ContentReader.
+ */
+ public ContentReader getReader(int version, String path);
+ /**
+ * Get a ContentWriter to a file.
+ * @param path The path to the file.
+ * @return A ContentWriter.
+ */
+ public ContentWriter getWriter(String path);
+
/**
* Get a listing of the designated directory.
* @param version The version to look under.
@@ -134,15 +151,6 @@ interface AVMStore
*/
public OutputStream getOutputStream(String path);
- /**
- * Get a random access file to the given file.
- * @param version The version id (read-only if not -1)
- * @param path The path to the file.
- * @param access The access for RandomAccessFile.
- * @return A RandomAccessFile.
- */
- public RandomAccessFile getRandomAccess(int version, String path, String access);
-
/**
* Remove a node and all of its contents.
* @param path The path to the node's parent directory.
@@ -336,4 +344,26 @@ interface AVMStore
* @param name The name of the property to delete.
*/
public void deleteProperty(QName name);
+
+ /**
+ * Get the ContentData on a file.
+ * @param version The version to look under.
+ * @param path The path to the file.
+ * @return The ContentData corresponding to the file.
+ */
+ public ContentData getContentDataForRead(int version, String path);
+
+ /**
+ * Get the ContentData for writing.
+ * @param path The path to the file.
+ * @return The ContentData object.
+ */
+ public ContentData getContentDataForWrite(String path);
+
+ /**
+ * Set the ContentData for a file.
+ * @param path The path to the file.
+ * @param data The ContentData to set.
+ */
+ public void setContentData(String path, ContentData data);
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java
index deb471f174..5a6f698875 100644
--- a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java
+++ b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java
@@ -20,7 +20,6 @@ package org.alfresco.repo.avm;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.RandomAccessFile;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
@@ -33,6 +32,10 @@ import java.util.TreeMap;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
+import org.alfresco.service.cmr.repository.ContentData;
+import org.alfresco.service.cmr.repository.ContentReader;
+import org.alfresco.service.cmr.repository.ContentWriter;
+import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
@@ -231,7 +234,12 @@ class AVMStoreImpl implements AVMStore, Serializable
file.setVersionID(getNextVersionID());
dir.putChild(name, file);
dir.updateModTime();
- return file.getContentForWrite().getOutputStream();
+ file.setContentData(new ContentData(null,
+ AVMContext.fgInstance.getMimetypeService().guessMimetype(name),
+ -1,
+ "UTF-8"));
+ ContentWriter writer = getWriter(AVMNodeConverter.ExtendAVMPath(path, name));
+ return writer.getContentOutputStream();
}
/**
@@ -248,10 +256,17 @@ class AVMStoreImpl implements AVMStore, Serializable
{
throw new AVMExistsException("Child exists: " + name);
}
- PlainFileNodeImpl file = new PlainFileNodeImpl(this, data);
+ PlainFileNodeImpl file = new PlainFileNodeImpl(this);
file.setVersionID(getNextVersionID());
dir.putChild(name, file);
dir.updateModTime();
+ file.setContentData(new ContentData(null,
+ AVMContext.fgInstance.getMimetypeService().guessMimetype(name),
+ -1,
+ "UTF-8"));
+ ContentWriter writer = getWriter(AVMNodeConverter.ExtendAVMPath(path, name));
+ writer.putContent(data);
+ file.setContentData(writer.getContentData());
}
/**
@@ -284,6 +299,9 @@ class AVMStoreImpl implements AVMStore, Serializable
*/
public InputStream getInputStream(int version, String path)
{
+ ContentReader reader = getReader(version, path);
+ return reader.getContentInputStream();
+ /*
Lookup lPath = lookup(version, path, false);
AVMNode node = lPath.getCurrentNode();
if (node.getType() != AVMNodeType.PLAIN_FILE &&
@@ -294,8 +312,35 @@ class AVMStoreImpl implements AVMStore, Serializable
FileNode file = (FileNode)node;
FileContent content = file.getContentForRead();
return content.getInputStream();
+ */
}
+ /**
+ * Get a ContentReader from a file.
+ * @param version The version to look under.
+ * @param path The path to the file.
+ * @return A ContentReader.
+ */
+ public ContentReader getReader(int version, String path)
+ {
+ NodeRef nodeRef = AVMNodeConverter.ToNodeRef(version, fName + ":" + path);
+ return AVMContext.fgInstance.getContentService().getReader(nodeRef, ContentModel.PROP_CONTENT);
+ }
+
+ /**
+ * Get a ContentWriter to a file.
+ * @param path The path to the file.
+ * @return A ContentWriter.
+ */
+ public ContentWriter getWriter(String path)
+ {
+ NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, fName + ":" + path);
+ ContentWriter writer =
+ AVMContext.fgInstance.getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
+ setContentData(path, writer.getContentData());
+ return writer;
+ }
+
/**
* Get a listing from a directory.
* @param version The version to look under.
@@ -368,6 +413,9 @@ class AVMStoreImpl implements AVMStore, Serializable
*/
public OutputStream getOutputStream(String path)
{
+ ContentWriter writer = getWriter(path);
+ return writer.getContentOutputStream();
+ /*
Lookup lPath = lookup(-1, path, true);
AVMNode node = lPath.getCurrentNode();
if (node.getType() != AVMNodeType.PLAIN_FILE &&
@@ -379,41 +427,7 @@ class AVMStoreImpl implements AVMStore, Serializable
FileContent content = file.getContentForWrite();
file.updateModTime();
return content.getOutputStream();
- }
-
- /**
- * Get a RandomAccessFile to a file node.
- * @param version The version.
- * @param path The path to the file.
- * @param access The access mode for RandomAccessFile.
- * @return A RandomAccessFile.
- */
- public RandomAccessFile getRandomAccess(int version, String path, String access)
- {
- boolean write = access.indexOf("rw") == 0;
- if (write && version >= 0)
- {
- throw new AVMException("Access denied: " + path);
- }
- Lookup lPath = lookup(version, path, write);
- AVMNode node = lPath.getCurrentNode();
- if (node.getType() != AVMNodeType.PLAIN_FILE &&
- node.getType() != AVMNodeType.LAYERED_FILE)
- {
- throw new AVMWrongTypeException("Not a file: " + path);
- }
- FileNode file = (FileNode)node;
- FileContent content = null;
- if (write)
- {
- content = file.getContentForWrite();
- file.updateModTime();
- }
- else
- {
- content = file.getContentForRead();
- }
- return content.getRandomAccess(access);
+ */
}
/**
@@ -968,4 +982,53 @@ class AVMStoreImpl implements AVMStore, Serializable
{
AVMContext.fgInstance.fAVMStorePropertyDAO.delete(this, name);
}
+
+ /**
+ * Get the ContentData on a file.
+ * @param version The version to look under.
+ * @param path The path to the file.
+ * @return The ContentData corresponding to the file.
+ */
+ public ContentData getContentDataForRead(int version, String path)
+ {
+ Lookup lPath = lookup(version, path, false);
+ AVMNode node = lPath.getCurrentNode();
+ if (!(node instanceof FileNode))
+ {
+ throw new AVMWrongTypeException("File Expected.");
+ }
+ return ((FileNode)node).getContentData(lPath);
+ }
+
+ /**
+ * Get the ContentData on a file for writing.
+ * @param path The path to the file.
+ * @return The ContentData corresponding to the file.
+ */
+ public ContentData getContentDataForWrite(String path)
+ {
+ Lookup lPath = lookup(-1, path, true);
+ AVMNode node = lPath.getCurrentNode();
+ if (!(node instanceof FileNode))
+ {
+ throw new AVMWrongTypeException("File Expected.");
+ }
+ return ((FileNode)node).getContentData(lPath);
+ }
+
+ /**
+ * Set the ContentData for a file.
+ * @param path The path to the file.
+ * @param data The ContentData to set.
+ */
+ public void setContentData(String path, ContentData data)
+ {
+ Lookup lPath = lookup(-1, path, true);
+ AVMNode node = lPath.getCurrentNode();
+ if (!(node instanceof FileNode))
+ {
+ throw new AVMWrongTypeException("File Expected.");
+ }
+ ((FileNode)node).setContentData(data);
+ }
}
diff --git a/source/java/org/alfresco/repo/avm/FileContent.java b/source/java/org/alfresco/repo/avm/FileContent.java
deleted file mode 100644
index e4b9b357fd..0000000000
--- a/source/java/org/alfresco/repo/avm/FileContent.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2006 Alfresco, Inc.
- *
- * Licensed under the Mozilla Public License version 1.1
- * with a permitted attribution clause. You may obtain a
- * copy of the License at
- *
- * http://www.alfresco.org/legal/license.txt
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the
- * License.
- */
-package org.alfresco.repo.avm;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-
-/**
- * Interface for file content. FileContent can be shared between files.
- * @author britt
- */
-interface FileContent
-{
- /**
- * Get the number of files that refer to this content.
- * @return The reference count.
- */
- public int getRefCount();
-
- /**
- * Set the reference count.
- * @param count The count to set.
- */
- public void setRefCount(int count);
-
- /**
- * Get an input stream from the content.
- * @return An InputStream.
- */
- public InputStream getInputStream();
-
- /**
- * Get an output stream to the content.
- * @return an OutputStream.
- */
- public OutputStream getOutputStream();
-
- /**
- * Get a random access file to this content.
- * @param access The mode to open the file in.
- * @return A RandomAccessFile.
- */
- public RandomAccessFile getRandomAccess(String access);
-
- /**
- * Delete the contents of this from the backing store.
- */
- public void delete();
-
- /**
- * Get the length of the file.
- * @return The length of the file.
- */
- public long getLength();
-
- /**
- * Get the object id.
- * @return object id.
- */
- public long getId();
-}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/avm/FileContentDAO.java b/source/java/org/alfresco/repo/avm/FileContentDAO.java
deleted file mode 100644
index b3d0abe189..0000000000
--- a/source/java/org/alfresco/repo/avm/FileContentDAO.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2006 Alfresco, Inc.
- *
- * Licensed under the Mozilla Public License version 1.1
- * with a permitted attribution clause. You may obtain a
- * copy of the License at
- *
- * http://www.alfresco.org/legal/license.txt
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the
- * License.
- */
-
-package org.alfresco.repo.avm;
-
-/**
- * DAO for FileContent objects.
- * @author britt
- */
-interface FileContentDAO
-{
- /**
- * Save one.
- * @param content To be saved.
- */
- public void save(FileContent content);
-
- /**
- * Delete one.
- * @param content To be deleted.
- */
- public void delete(FileContent content);
-}
diff --git a/source/java/org/alfresco/repo/avm/FileContentDAOHibernate.java b/source/java/org/alfresco/repo/avm/FileContentDAOHibernate.java
deleted file mode 100644
index 4747197dc5..0000000000
--- a/source/java/org/alfresco/repo/avm/FileContentDAOHibernate.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2006 Alfresco, Inc.
- *
- * Licensed under the Mozilla Public License version 1.1
- * with a permitted attribution clause. You may obtain a
- * copy of the License at
- *
- * http://www.alfresco.org/legal/license.txt
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the
- * License.
- */
-
-package org.alfresco.repo.avm;
-
-import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
-
-/**
- * @author britt
- *
- */
-class FileContentDAOHibernate extends HibernateDaoSupport implements
- FileContentDAO
-{
- /**
- * Do nothing constructor.
- */
- public FileContentDAOHibernate()
- {
- super();
- }
-
- /**
- * Save one.
- * @param content The one to save.
- */
- public void save(FileContent content)
- {
- getSession().save(content);
- }
-
- /**
- * Delete one.
- * @param content To be deleted.
- */
- public void delete(FileContent content)
- {
- getSession().delete(content);
- }
-}
diff --git a/source/java/org/alfresco/repo/avm/FileContentImpl.java b/source/java/org/alfresco/repo/avm/FileContentImpl.java
deleted file mode 100644
index 7855cfae4b..0000000000
--- a/source/java/org/alfresco/repo/avm/FileContentImpl.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2006 Alfresco, Inc.
- *
- * Licensed under the Mozilla Public License version 1.1
- * with a permitted attribution clause. You may obtain a
- * copy of the License at
- *
- * http://www.alfresco.org/legal/license.txt
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the
- * License.
- */
-
-package org.alfresco.repo.avm;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-import java.io.Serializable;
-import java.util.Formatter;
-
-/**
- * Content that is readable and writeable.
- * @author britt
- */
-class FileContentImpl implements FileContent, Serializable
-{
- static final long serialVersionUID = -7450825236235397307L;
-
- /**
- * The Object ID.
- */
- private long fID;
-
- /**
- * The reference count of this FileContent.
- */
- private int fRefCount;
-
- /**
- * The version (for concurrency control).
- */
- private long fVers;
-
- /**
- * The name of the file.
- */
- private String fName;
-
- /**
- * The directory path of the file.
- */
- private String fPath;
-
- /**
- * Default constructor.
- */
- public FileContentImpl()
- {
- fName = null;
- fPath = null;
- }
-
- /**
- * Make a brand new one.
- * @param id The id for this content.
- */
- public FileContentImpl(long id)
- {
- fID = id;
- fRefCount = 1;
- // Initialize the contents.
- try
- {
- OutputStream out = getOutputStream();
- out.close();
- }
- catch (IOException ie)
- {
- throw new AVMException("File data error.", ie);
- }
- AVMContext.fgInstance.fFileContentDAO.save(this);
- }
-
- /**
- * Initialize with the given content.
- * @param id
- * @param content
- */
- public FileContentImpl(long id, File content)
- {
- fID = id;
- fRefCount = 1;
- // Initialize the contents.
- try
- {
- OutputStream out = getOutputStream();
- InputStream in = new FileInputStream(content);
- byte [] buff = new byte[8192];
- int count;
- while ((count = in.read(buff)) != -1)
- {
- out.write(buff, 0, count);
- }
- out.close();
- in.close();
- }
- catch (IOException ie)
- {
- throw new AVMException("I/O Error.", ie);
- }
- AVMContext.fgInstance.fFileContentDAO.save(this);
- }
-
- /**
- * Copy constructor, sort of.
- * @param other The content to copy from.
- * @param id The id for this content.
- */
- public FileContentImpl(FileContent other, long id)
- {
- fID = id;
- fRefCount = 1;
- // Copy the contents from other to this.
- BufferedInputStream in = new BufferedInputStream(other.getInputStream());
- BufferedOutputStream out = new BufferedOutputStream(getOutputStream());
- try
- {
- byte [] buff = new byte[4096]; // Nyah, nyah.
- int bytesRead;
- while ((bytesRead = in.read(buff)) != -1)
- {
- out.write(buff, 0, bytesRead);
- }
- out.flush();
- out.close();
- in.close();
- }
- catch (IOException ie)
- {
- throw new AVMException("I/O failure in Copy on Write.", ie);
- }
- AVMContext.fgInstance.fFileContentDAO.save(this);
- }
-
- /**
- * Get this FileContent's reference count.
- * @return The reference count.
- */
- public int getRefCount()
- {
- return fRefCount;
- }
-
- /**
- * Set the reference count on this.
- * @param count The reference count to set.
- */
- public void setRefCount(int count)
- {
- fRefCount = count;
- }
-
- /**
- * Get an InputStream from this FileContent.
- * @return An InputStream.
- */
- public InputStream getInputStream()
- {
- try
- {
- return new FileInputStream(getContentPath());
- }
- catch (IOException ie)
- {
- throw new AVMException("Could not open for reading: " + getContentPath(), ie);
- }
- }
-
- /**
- * Gets an ouptut stream to this node.
- * @return An OutputStream.
- */
- public OutputStream getOutputStream()
- {
- try
- {
- File dir = new File(getDirectoryPath());
- if (!dir.exists())
- {
- dir.mkdirs();
- }
- return new FileOutputStream(getContentPath());
- }
- catch (IOException ie)
- {
- throw new AVMException("Could not open for writing: " + getContentPath(), ie);
- }
- }
-
- /**
- * Get a random access file from this content. It's the responsibility of
- * the caller of this to insure that this object has been copied if the
- * access argument is a write mode.
- * @param access The access more for RandomAccessFile.
- * @return A RandomAccessFile.
- */
- public RandomAccessFile getRandomAccess(String access)
- {
- try
- {
- return new RandomAccessFile(getContentPath(), access);
- }
- catch (IOException ie)
- {
- throw new AVMException("Could not open for random access: " + getContentPath(), ie);
- }
- }
-
- /**
- * Delete the contents of this file from the backing store.
- */
- public void delete()
- {
- File file = new File(getContentPath());
- file.delete();
- }
-
- /**
- * Get the length of this content.
- * @return The length of the content.
- */
- public long getLength()
- {
- File file = new File(getContentPath());
- return file.length();
- }
-
- /**
- * Retrieve the full path for this content.
- * @return The full path for this content.
- */
- private synchronized String getContentPath()
- {
- if (fName == null)
- {
- calcPathData();
- }
- return fName;
- }
-
- /**
- * Get the directory path for this content.
- * @return The directory path.
- */
- private synchronized String getDirectoryPath()
- {
- if (fPath == null)
- {
- calcPathData();
- }
- return fPath;
- }
-
- /**
- * Calculate the path data.
- */
- private void calcPathData()
- {
- Formatter form = new Formatter(new StringBuilder());
- form.format("%016x", fID);
- String name = form.toString();
- form = new Formatter(new StringBuilder());
- form.format("/%02x/%02x/%02x",
- (fID & 0xff000000) >> 24,
- (fID & 0xff0000) >> 16,
- (fID & 0xff00) >> 8);
- String dir = form.toString();
- fPath = AVMRepository.GetInstance().getStorageRoot() + dir;
- fName = fPath + "/" + name;
- }
-
- /**
- * Set the version for concurrency control.
- * @param vers The value to set.
- */
- protected void setVers(long vers)
- {
- fVers = vers;
- }
-
- /**
- * Get the version for concurrency control.
- * @return The version.
- */
- protected long getVers()
- {
- return fVers;
- }
-
- /**
- * Set the object id. For Hibernate.
- * @param id
- */
- protected void setId(long id)
- {
- fID = id;
- }
-
- /**
- * Get the object id.
- * @return The object id.
- */
- public long getId()
- {
- return fID;
- }
-
- /**
- * Equals predicate. Based on object ID.
- * @param obj The obect to compare against.
- * @return Equality.
- */
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- if (!(obj instanceof FileContent))
- {
- return false;
- }
- return fID == ((FileContent)obj).getId();
- }
-
- /**
- * Generate a hashCode.
- * @return The hashCode.
- */
- @Override
- public int hashCode()
- {
- return (int)fID;
- }
-}
diff --git a/source/java/org/alfresco/repo/avm/FileNode.java b/source/java/org/alfresco/repo/avm/FileNode.java
index 7d9ca08885..f993c83b05 100644
--- a/source/java/org/alfresco/repo/avm/FileNode.java
+++ b/source/java/org/alfresco/repo/avm/FileNode.java
@@ -16,6 +16,8 @@
*/
package org.alfresco.repo.avm;
+import org.alfresco.service.cmr.repository.ContentData;
+
/**
* Interface for the generic idea of a file.
* @author britt
@@ -23,15 +25,15 @@ package org.alfresco.repo.avm;
interface FileNode extends AVMNode
{
/**
- * Get the content object associated with this node, for reading.
- * @return A FileContent object.
+ * Set the ContentData for this file.
+ * @param contentData The value to set.
*/
- public FileContent getContentForRead();
-
+ public void setContentData(ContentData contentData);
+
/**
- * Get the content object for writing. This will do COW
- * as needed.
- * @return A FileContent object.
+ * Get the ContentData for this file.
+ * @param lPath The Lookup used to get here.
+ * @return The ContentData object for this file.
*/
- public FileContent getContentForWrite();
+ public ContentData getContentData(Lookup lPath);
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java
index ff91e06ad9..bd4e0e7173 100644
--- a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java
+++ b/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java
@@ -17,6 +17,8 @@
package org.alfresco.repo.avm;
+import org.alfresco.service.cmr.repository.ContentData;
+
/**
* A LayeredFileNode behaves like a copy on write symlink.
* @author britt
@@ -81,13 +83,10 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
{
throw new AVMException("Unbacked layered file node.");
}
- // This is a mildly dirty trick. We use getContentForRead so as not to startle
- // the ultimate destination content into copying itself prematurely.
- FileContent content = ((FileNode)indirect).getContentForRead();
- PlainFileNodeImpl newMe = new PlainFileNodeImpl(this,
- content,
- lPath.getAVMStore(),
- getBasicAttributes());
+ PlainFileNodeImpl newMe = new PlainFileNodeImpl(lPath.getAVMStore(),
+ getBasicAttributes(),
+ getContentData(lPath),
+ getProperties());
newMe.setAncestor(this);
return newMe;
}
@@ -101,33 +100,6 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
return AVMNodeType.LAYERED_FILE;
}
- /**
- * Get the content of the specified version.
- * @return A FileContent object.
- */
- public FileContent getContentForRead()
- {
- Lookup lookup = AVMRepository.GetInstance().lookup(-1, fIndirection);
- AVMNode node = lookup.getCurrentNode();
- if (node.getType() != AVMNodeType.LAYERED_FILE &&
- node.getType() != AVMNodeType.PLAIN_FILE)
- {
- throw new AVMException("Missing Link.");
- }
- FileNode file = (FileNode)node;
- return file.getContentForRead();
- }
-
- /**
- * Get File Content for writing. Should never be called.
- * @return Always null.
- */
- public FileContent getContentForWrite()
- {
- assert false : "Never happens";
- return null;
- }
-
/**
* Get the underlying path.
* @param lookup The Lookup. (Unused here.)
@@ -256,4 +228,29 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
{
fIndirection = indirection;
}
+
+ /**
+ * Set the ContentData for this file.
+ * @param contentData The value to set.
+ */
+ public void setContentData(ContentData contentData)
+ {
+ throw new AVMException("Should not be called.");
+ }
+
+ /**
+ * Get the ContentData for this file.
+ * @return The ContentData object for this file.
+ */
+ public ContentData getContentData(Lookup lPath)
+ {
+ Lookup lookup = lPath.getAVMStore().getAVMRepository().lookup(-1, getIndirection());
+ AVMNode node = lookup.getCurrentNode();
+ if (!(node instanceof FileNode))
+ {
+ throw new AVMException("Invalid target.");
+ }
+ FileNode file = (FileNode)node;
+ return file.getContentData(lookup);
+ }
}
diff --git a/source/java/org/alfresco/repo/avm/OrphanReaper.java b/source/java/org/alfresco/repo/avm/OrphanReaper.java
index 92649bc4da..f727c62ec8 100644
--- a/source/java/org/alfresco/repo/avm/OrphanReaper.java
+++ b/source/java/org/alfresco/repo/avm/OrphanReaper.java
@@ -295,17 +295,7 @@ class OrphanReaper implements Runnable
}
AVMContext.fgInstance.fAVMNodeDAO.delete(node);
}
- else if (node.getType() == AVMNodeType.PLAIN_FILE)
- {
- AVMContext.fgInstance.fAVMNodeDAO.delete(node);
- // FileContent should be purged if nobody else references it.
- FileContent content = ((PlainFileNode)node).getContent();
- if (content.getRefCount() == 1)
- {
- content.delete();
- AVMContext.fgInstance.fFileContentDAO.delete(content);
- }
- }
+ // TODO Need to properly clean up deleted files.
else
{
AVMContext.fgInstance.fAVMNodeDAO.delete(node);
diff --git a/source/java/org/alfresco/repo/avm/PlainFileNode.java b/source/java/org/alfresco/repo/avm/PlainFileNode.java
index 80b603cbc3..00a1cf878f 100644
--- a/source/java/org/alfresco/repo/avm/PlainFileNode.java
+++ b/source/java/org/alfresco/repo/avm/PlainFileNode.java
@@ -6,5 +6,4 @@ package org.alfresco.repo.avm;
*/
interface PlainFileNode extends FileNode
{
- public FileContent getContent();
}
diff --git a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java b/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java
index 742fb4bba6..a9a0ee0c27 100644
--- a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java
+++ b/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java
@@ -17,7 +17,12 @@
package org.alfresco.repo.avm;
-import java.io.File;
+import java.util.Map;
+
+import org.alfresco.repo.domain.PropertyValue;
+import org.alfresco.service.cmr.repository.ContentData;
+import org.alfresco.service.cmr.repository.ContentReader;
+import org.alfresco.service.namespace.QName;
/**
@@ -29,9 +34,24 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
static final long serialVersionUID = 8720376837929735294L;
/**
- * The file content.
+ * The Content URL.
*/
- private FileContent fContent;
+ private String fContentURL;
+
+ /**
+ * The Mime type.
+ */
+ private String fMimeType;
+
+ /**
+ * The character encoding.
+ */
+ private String fEncoding;
+
+ /**
+ * The length of the file.
+ */
+ private long fLength;
/**
* Default constructor.
@@ -48,27 +68,12 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
public PlainFileNodeImpl(AVMStore store)
{
super(store.getAVMRepository().issueID(), store);
- fContent = new FileContentImpl(AVMRepository.GetInstance().issueContentID());
// AVMContext.fgInstance.fAVMNodeDAO.flush();
AVMContext.fgInstance.fAVMNodeDAO.save(this);
AVMContext.fgInstance.fAVMNodeDAO.flush();
AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(store, this));
}
- /**
- * Create a new plain file with given content.
- * @param store The store.
- * @param content The content to set.
- */
- public PlainFileNodeImpl(AVMStore store, File content)
- {
- super(store.getAVMRepository().issueID(), store);
- fContent = new FileContentImpl(AVMRepository.GetInstance().issueContentID(), content);
- AVMContext.fgInstance.fAVMNodeDAO.save(this);
- AVMContext.fgInstance.fAVMNodeDAO.flush();
- AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(store, this));
- }
-
/**
* Copy on write constructor.
* @param other The node we are being copied from.
@@ -78,8 +83,9 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
AVMStore store)
{
super(store.getAVMRepository().issueID(), store);
- fContent = other.getContent();
- fContent.setRefCount(fContent.getRefCount() + 1);
+ // The null is OK because the Lookup argument is only use by
+ // layered files.
+ setContentData(other.getContentData(null));
AVMContext.fgInstance.fAVMNodeDAO.save(this);
AVMContext.fgInstance.fAVMNodeDAO.flush();
AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(store, this));
@@ -87,24 +93,26 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
}
/**
- * Constructor that takes a FileContent to share. Called by LayeredFileNodeImpl.copy().
- * @param content The FileContent to share.
- * @param store The AVMStore.
+ * Construct a new one. This is called when a LayeredFileNode
+ * is copied.
+ * @param store
+ * @param attrs
+ * @param content
*/
- public PlainFileNodeImpl(LayeredFileNode other,
- FileContent content,
- AVMStore store,
- BasicAttributes oAttrs)
+ public PlainFileNodeImpl(AVMStore store,
+ BasicAttributes attrs,
+ ContentData content,
+ Map props)
{
super(store.getAVMRepository().issueID(), store);
- fContent = content;
- fContent.setRefCount(fContent.getRefCount() + 1);
+ setContentData(content);
+ setBasicAttributes(attrs);
AVMContext.fgInstance.fAVMNodeDAO.save(this);
AVMContext.fgInstance.fAVMNodeDAO.flush();
+ this.setProperties(props);
AVMContext.fgInstance.fNewInAVMStoreDAO.save(new NewInAVMStoreImpl(store, this));
- copyProperties(other);
}
-
+
/**
* Copy on write logic.
* @param lPath The lookup path.
@@ -125,25 +133,6 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
return AVMNodeType.PLAIN_FILE;
}
- /**
- * Get content for reading.
- */
- public FileContent getContentForRead()
- {
- return fContent;
- }
- /**
- * Get content for writing.
- */
- public FileContent getContentForWrite()
- {
- if (fContent.getRefCount() > 1)
- {
- fContent = new FileContentImpl(fContent, AVMRepository.GetInstance().issueContentID());
- }
- return fContent;
- }
-
/**
* Get a diagnostic string representation.
* @param lPath The Lookup.
@@ -187,7 +176,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
false,
-1,
false,
- getContentForRead().getLength());
+ getLength());
}
/**
@@ -214,7 +203,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
false,
-1,
false,
- getContentForRead().getLength());
+ getFileLength());
}
/**
@@ -243,25 +232,115 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
false,
-1,
false,
- getContentForRead().getLength());
+ getFileLength());
}
/**
- * Get the file content of this node.
- * @return The file content object.
+ * Get the Content URL.
+ * @return The content URL.
*/
- public FileContent getContent()
+ public String getContentURL()
{
- return fContent;
+ return fContentURL;
+ }
+
+ /**
+ * Set the Content URL.
+ * @param contentURL
+ */
+ protected void setContentURL(String contentURL)
+ {
+ fContentURL = contentURL;
+ }
+
+ /**
+ * Get the character encoding.
+ * @return The encoding.
+ */
+ public String getEncoding()
+ {
+ return fEncoding;
+ }
+
+ /**
+ * Set the character encoding.
+ * @param encoding The encoding to set.
+ */
+ protected void setEncoding(String encoding)
+ {
+ fEncoding = encoding;
+ }
+
+ /**
+ * Get the file length.
+ * @return The file length or null if unknown.
+ */
+ public long getLength()
+ {
+ return fLength;
}
/**
- * Set the FileContent for this file.
- * @param content
+ * Get the actual file length.
+ * @return The actual file length;
*/
- protected void setContent(FileContent content)
+ private long getFileLength()
{
- fContent = content;
+ ContentReader reader = AVMContext.fgInstance.getContentStore().getReader(fContentURL);
+ return reader.getSize();
+ }
+
+ /**
+ * Set the file length.
+ * @param length The length of the file.
+ */
+ protected void setLength(long length)
+ {
+ fLength = length;
+ }
+
+ /**
+ * Get the mime type of the content.
+ * @return The Mime Type of the content.
+ */
+ public String getMimeType()
+ {
+ return fMimeType;
+ }
+
+ /**
+ * Set the Mime Type of the content.
+ * @param mimeType The Mime Type to set.
+ */
+ protected void setMimeType(String mimeType)
+ {
+ fMimeType = mimeType;
+ }
+
+ /**
+ * Set the ContentData for this file.
+ * @param contentData The value to set.
+ */
+ public void setContentData(ContentData contentData)
+ {
+ fContentURL = contentData.getContentUrl();
+ fMimeType = contentData.getMimetype();
+ if (fMimeType == null)
+ {
+ throw new AVMException("Null mime type.");
+ }
+ fEncoding = contentData.getEncoding();
+ fLength = contentData.getSize();
+ }
+
+ /**
+ * Get the ContentData for this file.
+ * @param lPath The lookup path used to get here. Unused here.
+ * @return The ContentData object for this file.
+ */
+ public ContentData getContentData(Lookup lPath)
+ {
+ return new ContentData(fContentURL, fMimeType, fLength, fEncoding);
}
}
diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml b/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml
index b7597cb21a..a6a87e914e 100644
--- a/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml
+++ b/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml
@@ -77,9 +77,10 @@
-
-
+
+
+
+
-
-
-
-
-
-
-
-