mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
ALF-10686 - Original modification date is lost when files are copied into Alfresco via CIFS
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@31864 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -251,21 +251,40 @@ public class BufferedContentDiskDriver implements ExtendedDiskInterface,
|
||||
FileInfo finfo = new FileInfo();
|
||||
finfo.copyFrom(info);
|
||||
|
||||
// TODO what if file state cache is stale or wrong? We are over-writing the "real" value.
|
||||
/*
|
||||
* TODO what if file state cache is stale?
|
||||
* We are over-writing the "real" value here.
|
||||
*/
|
||||
if(fstate.hasFileSize())
|
||||
{
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("replace file size " + info.getSize() + " with " + fstate.getFileSize());
|
||||
}
|
||||
finfo.setFileSize(fstate.getFileSize());
|
||||
}
|
||||
if ( fstate.hasAccessDateTime())
|
||||
{
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("replace access date " + new Date(finfo.getAccessDateTime()) + " with " + new Date(fstate.getAccessDateTime()));
|
||||
}
|
||||
finfo.setAccessDateTime(fstate.getAccessDateTime());
|
||||
}
|
||||
if ( fstate.hasChangeDateTime())
|
||||
{
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("replace change date " + new Date(finfo.getChangeDateTime()) + " with " + new Date(fstate.getChangeDateTime()));
|
||||
}
|
||||
finfo.setChangeDateTime(fstate.getChangeDateTime());
|
||||
}
|
||||
if ( fstate.hasModifyDateTime())
|
||||
{
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("replace modified date " + new Date(finfo.getModifyDateTime()) + " with " + new Date(fstate.getModifyDateTime()));
|
||||
}
|
||||
finfo.setModifyDateTime(fstate.getModifyDateTime());
|
||||
}
|
||||
if ( fstate.hasAllocationSize() && fstate.getAllocationSize() > info.getAllocationSize())
|
||||
@@ -279,8 +298,10 @@ public class BufferedContentDiskDriver implements ExtendedDiskInterface,
|
||||
", readOnly:" +finfo.isReadOnly() +
|
||||
", fileId:" +finfo.getFileId() +
|
||||
", directoryId:" + finfo.getDirectoryId() +
|
||||
", createdDate: " + finfo.getCreationDateTime() +
|
||||
", accessDate:" + new Date(finfo.getAccessDateTime()) +
|
||||
", modifiedDate:" + new Date(finfo.getModifyDateTime()) +
|
||||
", changeDate:" + new Date(finfo.getChangeDateTime()) +
|
||||
", mode" + finfo.getMode());
|
||||
}
|
||||
|
||||
|
@@ -277,6 +277,7 @@ public class CifsHelper
|
||||
long modified = DefaultTypeConverter.INSTANCE.longValue(modifiedDate);
|
||||
fileInfo.setModifyDateTime(modified);
|
||||
fileInfo.setAccessDateTime(modified);
|
||||
fileInfo.setChangeDateTime(modified);
|
||||
}
|
||||
// name
|
||||
String name = fileFolderInfo.getName();
|
||||
|
@@ -1968,6 +1968,8 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
|
||||
logger.debug("setFileInformation name=" + name + ", info=" + info);
|
||||
}
|
||||
|
||||
NetworkFile networkFile = info.getNetworkFile();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -2057,12 +2059,28 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
|
||||
// Set the creation date on the file/folder node
|
||||
Date createDate = new Date( info.getCreationDateTime());
|
||||
auditableProps.put(ContentModel.PROP_CREATED, createDate);
|
||||
if ( logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Set creation date" + name + ", " + createDate);
|
||||
}
|
||||
}
|
||||
if ( info.hasSetFlag(FileInfo.SetModifyDate))
|
||||
{
|
||||
// Set the modification date on the file/folder node
|
||||
Date modifyDate = new Date( info.getModifyDateTime());
|
||||
auditableProps.put(ContentModel.PROP_MODIFIED, modifyDate);
|
||||
|
||||
// Set the network file so we don't reverse this change in close file.
|
||||
if(networkFile != null && !networkFile.isReadOnly())
|
||||
{
|
||||
networkFile.setModifyDate(info.getModifyDateTime());
|
||||
}
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Set modification date" + name + ", " + modifyDate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Did we have any cm:auditable properties?
|
||||
@@ -2880,6 +2898,13 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD
|
||||
tempFile.flushFile();
|
||||
tempFile.close();
|
||||
|
||||
/**
|
||||
* Take over the behaviour of the auditable aspect
|
||||
*/
|
||||
getPolicyFilter().disableBehaviour(target, ContentModel.ASPECT_AUDITABLE);
|
||||
nodeService.setProperty(target, ContentModel.PROP_MODIFIER, authService.getCurrentUserName());
|
||||
nodeService.setProperty(target, ContentModel.PROP_MODIFIED, new Date(tempFile.getModifyDate()));
|
||||
|
||||
// Take an initial guess at the mimetype (if it has not been set by something already)
|
||||
String mimetype = mimetypeService.guessMimetype(tempFile.getFullName(), new FileContentReader(tempFile.getFile()));
|
||||
logger.debug("guesssed mimetype:" + mimetype);
|
||||
|
@@ -3762,6 +3762,122 @@ public class ContentDiskDriverTest extends TestCase
|
||||
|
||||
} // Test Word Save Locked File
|
||||
|
||||
/**
|
||||
* ALF-10686
|
||||
* This scenario is executed by windows explorer.
|
||||
*
|
||||
* A file is created and the file handle kept open.
|
||||
* stuff is written
|
||||
* Then the modified date is set
|
||||
* Then the file is closed.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testSetFileScenario() throws Exception
|
||||
{
|
||||
logger.debug("testSetFileInfo");
|
||||
ServerConfiguration scfg = new ServerConfiguration("testServer");
|
||||
TestServer testServer = new TestServer("testServer", scfg);
|
||||
final SrvSession testSession = new TestSrvSession(666, testServer, "test", "remoteName");
|
||||
DiskSharedDevice share = getDiskSharedDevice();
|
||||
final TreeConnection testConnection = testServer.getTreeConnection(share);
|
||||
final RetryingTransactionHelper tran = transactionService.getRetryingTransactionHelper();
|
||||
|
||||
Date now = new Date();
|
||||
|
||||
// CREATE 6 hours ago
|
||||
final Date CREATED = new Date(now.getTime() - 1000 * 60 * 60 * 6);
|
||||
// Modify one hour ago
|
||||
final Date MODIFIED = new Date(now.getTime() - 1000 * 60 * 60 * 1);
|
||||
|
||||
class TestContext
|
||||
{
|
||||
NodeRef testNodeRef;
|
||||
};
|
||||
|
||||
final TestContext testContext = new TestContext();
|
||||
|
||||
/**
|
||||
* Step 1 : Create a new file in read/write mode and add some content.
|
||||
* Call SetInfo to set the creation date
|
||||
*/
|
||||
int openAction = FileAction.CreateNotExist;
|
||||
|
||||
final String FILE_NAME="testSetFileScenario.txt";
|
||||
final String FILE_PATH="\\"+FILE_NAME;
|
||||
|
||||
// Clean up junk if it exists
|
||||
try
|
||||
{
|
||||
driver.deleteFile(testSession, testConnection, FILE_PATH);
|
||||
}
|
||||
catch (IOException ie)
|
||||
{
|
||||
// expect to go here
|
||||
}
|
||||
|
||||
final FileOpenParams params = new FileOpenParams(FILE_PATH, openAction, AccessMode.ReadWrite, FileAttribute.NTNormal, 0);
|
||||
|
||||
final NetworkFile file = driver.createFile(testSession, testConnection, params);
|
||||
assertNotNull("file is null", file);
|
||||
assertFalse("file is read only, should be read-write", file.isReadOnly());
|
||||
|
||||
RetryingTransactionCallback<Void> writeStuffCB = new RetryingTransactionCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
byte[] stuff = "Hello World".getBytes();
|
||||
|
||||
driver.writeFile(testSession, testConnection, file, stuff, 0, stuff.length, 0);
|
||||
|
||||
FileInfo info = driver.getFileInformation(testSession, testConnection, FILE_PATH);
|
||||
info.setFileInformationFlags(FileInfo.SetModifyDate);
|
||||
info.setModifyDateTime(MODIFIED.getTime());
|
||||
info.setNetworkFile(file);
|
||||
driver.setFileInformation(testSession, testConnection, FILE_PATH, info);
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
tran.doInTransaction(writeStuffCB);
|
||||
|
||||
RetryingTransactionCallback<Void> closeFileCB = new RetryingTransactionCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
// This close is in a different position to the simple setFileInformation scenarios above.
|
||||
driver.closeFile(testSession, testConnection, file);
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
tran.doInTransaction(closeFileCB);
|
||||
|
||||
RetryingTransactionCallback<Void> validateCB = new RetryingTransactionCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
NodeRef companyHome = repositoryHelper.getCompanyHome();
|
||||
NodeRef newNode = nodeService.getChildByName(companyHome, ContentModel.ASSOC_CONTAINS, FILE_NAME);
|
||||
testContext.testNodeRef = newNode;
|
||||
assertNotNull("can't find new node", newNode);
|
||||
Serializable content = nodeService.getProperty(newNode, ContentModel.PROP_CONTENT);
|
||||
assertNotNull("content is null", content);
|
||||
Date modified = (Date)nodeService.getProperty(newNode, ContentModel.PROP_MODIFIED);
|
||||
assertEquals("modified time not set correctly", MODIFIED, modified);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
tran.doInTransaction(validateCB);
|
||||
|
||||
|
||||
// clean up so we could run the test again
|
||||
//driver.deleteFile(testSession, testConnection, FILE_PATH);
|
||||
|
||||
} // test set modified scenario
|
||||
|
||||
/**
|
||||
* Test server
|
||||
*/
|
||||
|
@@ -20,6 +20,7 @@ package org.alfresco.filesys.repo;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.alfresco.filesys.alfresco.ExtendedDiskInterface;
|
||||
import org.alfresco.filesys.config.ServerConfigurationBean;
|
||||
@@ -37,6 +38,7 @@ import org.alfresco.jlan.server.filesys.cache.FileState;
|
||||
import org.alfresco.jlan.server.filesys.cache.FileStateCache;
|
||||
import org.alfresco.jlan.server.filesys.cache.NetworkFileStateInterface;
|
||||
import org.alfresco.jlan.smb.SharingMode;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -392,7 +394,35 @@ public class LegacyFileStateDriver implements ExtendedDiskInterface
|
||||
public void setFileInformation(SrvSession sess, TreeConnection tree,
|
||||
String name, FileInfo info) throws IOException
|
||||
{
|
||||
|
||||
diskInterface.setFileInformation(sess, tree, name, info);
|
||||
|
||||
ContentContext tctx = (ContentContext) tree.getContext();
|
||||
|
||||
if(tctx.hasStateCache())
|
||||
{
|
||||
FileStateCache cache = tctx.getStateCache();
|
||||
FileState fstate = cache.findFileState( name, true);
|
||||
|
||||
// if ( info.hasSetFlag(FileInfo.SetCreationDate))
|
||||
// {
|
||||
// if ( logger.isDebugEnabled())
|
||||
// {
|
||||
// logger.debug("Set creation date in file state cache" + name + ", " + info.getCreationDateTime());
|
||||
// }
|
||||
// Date createDate = new Date( info.getCreationDateTime());
|
||||
// fstate.u(createDate.getTime());
|
||||
// }
|
||||
if ( info.hasSetFlag(FileInfo.SetModifyDate))
|
||||
{
|
||||
if ( logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Set modification date in file state cache" + name + ", " + info.getModifyDateTime());
|
||||
}
|
||||
Date modifyDate = new Date( info.getModifyDateTime());
|
||||
fstate.updateModifyDateTime(modifyDate.getTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -20,6 +20,7 @@ package org.alfresco.filesys.repo;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -196,6 +197,12 @@ public class NonTransactionalRuleContentDiskDriver implements ExtendedDiskInterf
|
||||
+ " allocationSize: " + params.getAllocationSize());
|
||||
}
|
||||
|
||||
long creationDateTime = params.getCreationDateTime();
|
||||
if(creationDateTime != 0)
|
||||
{
|
||||
logger.debug("creationDateTime is set:" + new Date(creationDateTime));
|
||||
}
|
||||
|
||||
ContentContext tctx = (ContentContext) tree.getContext();
|
||||
NodeRef rootNode = tctx.getRootNode();
|
||||
|
||||
|
@@ -76,6 +76,7 @@ public class TempNetworkFile extends JavaNetworkFile implements NetworkFileState
|
||||
if(fileState != null)
|
||||
{
|
||||
fileState.updateModifyDateTime();
|
||||
fileState.updateAccessDateTime();
|
||||
fileState.setFileSize(size);
|
||||
}
|
||||
}
|
||||
@@ -92,6 +93,7 @@ public class TempNetworkFile extends JavaNetworkFile implements NetworkFileState
|
||||
if(fileState != null)
|
||||
{
|
||||
fileState.updateModifyDateTime();
|
||||
fileState.updateAccessDateTime();
|
||||
fileState.setFileSize(size);
|
||||
}
|
||||
}
|
||||
@@ -105,6 +107,7 @@ public class TempNetworkFile extends JavaNetworkFile implements NetworkFileState
|
||||
if(fileState != null)
|
||||
{
|
||||
fileState.updateModifyDateTime();
|
||||
fileState.updateAccessDateTime();
|
||||
fileState.setFileSize(size);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user