use of org.alfresco.jlan.server.filesys.cache.FileState in project alfresco-repository by Alfresco.
the class ContentDiskDriver method renameFile.
/**
* Rename the specified file.
*
* @param sess Server session
* @param tree Tree connection
* @param oldName java.lang.String
* @param newName java.lang.String
* @exception java.io.IOException The exception description.
*/
public void renameFile(final SrvSession sess, final TreeConnection tree, final String oldName, final String newName) throws IOException {
// Create the transaction (initially read-only)
beginReadTransaction(sess);
// Get the device context
final ContentContext ctx = (ContentContext) tree.getContext();
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename oldName=" + oldName + ", newName=" + newName);
try {
// Get the file/folder to move
final NodeRef nodeToMoveRef = getNodeForPath(tree, oldName);
if (nodeToMoveRef != null && nodeService.getProperty(nodeToMoveRef, ContentModel.PROP_LINK_DESTINATION) != null)
throw new AccessDeniedException("Cannot rename link nodes");
// Get the new target folder - it must be a folder
String[] splitPaths = FileName.splitPath(newName);
String[] oldPaths = FileName.splitPath(oldName);
final NodeRef targetFolderRef = getNodeForPath(tree, splitPaths[0]);
final NodeRef sourceFolderRef = getNodeForPath(tree, oldPaths[0]);
final String name = splitPaths[1];
// Check if this is a rename within the same folder
final boolean sameFolder = splitPaths[0].equalsIgnoreCase(oldPaths[0]);
// Get the file state for the old file, if available
final FileState oldState = ctx.getStateCache().findFileState(oldName, true);
// Check if we are renaming a folder, or the rename is to a different folder
boolean isFolder = cifsHelper.isDirectory(nodeToMoveRef);
if (isFolder == true || sameFolder == false) {
// Rename or move the file/folder
doInWriteTransaction(sess, new CallableIO<Void>() {
public Void call() throws IOException {
if (sameFolder == true)
cifsHelper.rename(nodeToMoveRef, name);
else
cifsHelper.move(nodeToMoveRef, sourceFolderRef, targetFolderRef, name);
return null;
}
});
if (oldState != null) {
// Update the file state index to use the new name
ctx.getStateCache().renameFileState(newName, oldState, isFolder);
}
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Renamed " + (isFolder ? "folder" : "file") + " using " + (sameFolder ? "rename" : "move"));
} else {
// Rename a file within the same folder
//
// Check if the target file already exists
final int newExists = fileExists(sess, tree, newName);
final FileState newState = ctx.getStateCache().findFileState(newName, true);
List<Runnable> postTxn = doInWriteTransaction(sess, new CallableIO<List<Runnable>>() {
public List<Runnable> call() throws IOException {
List<Runnable> postTxn = new LinkedList<Runnable>();
NodeRef targetNodeRef = null;
boolean isFromVersionable = nodeService.hasAspect(nodeToMoveRef, ContentModel.ASPECT_VERSIONABLE);
boolean typesCompatible = true;
// HACK ALF-3856: Version History lost when Versionable Content renamed via CIFS
// This code will move into the repo layer (or just above it)
// and this complexity removed from here.
// Attempt to detect normal renames. Hack alert!
Pattern renameShufflePattern = ctx.getRenameShufflePattern();
boolean renameShuffle = isRenameShuffle(oldName, newName, renameShufflePattern);
if (logger.isDebugEnabled()) {
logger.debug("Rename file: \n" + " Old name: " + oldName + "\n" + " New name: " + newName + "\n" + " Pattern: " + renameShufflePattern.pattern() + "\n" + " Is shuffle: " + renameShuffle + "\n" + " Source folder: " + sourceFolderRef + "\n" + " Target folder: " + targetFolderRef + "\n" + " Node: " + nodeToMoveRef + "\n" + " Aspects: " + nodeService.getAspects(nodeToMoveRef));
}
if (newExists == FileStatus.FileExists) {
// Use the existing file as the target node
targetNodeRef = getNodeForPath(tree, newName);
} else if (renameShuffle) {
logger.debug("is rename shuffle");
if (newState.getFileStatus() == FileRenamed) {
logger.debug("file status == FileRenamed");
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Using renamed node, " + newState);
NodeRef newStateNode = (NodeRef) newState.getFilesystemObject();
QName oldType = nodeService.getType(nodeToMoveRef);
QName newType = nodeService.getType(newStateNode);
if (oldType.equals(newType)) {
// Use the renamed node to clone aspects/state if it is of the correct type
cloneNode(name, newStateNode, nodeToMoveRef, ctx);
} else {
logger.debug("not renamed, must create new node");
// Otherwise we must create a node of the correct type
targetNodeRef = cifsHelper.createNode(ctx.getRootNode(), newName, newType);
// Force a copy to this target
typesCompatible = false;
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Created new node for " + newName + " type " + newType + ", isFromVersionable=false");
// Copy aspects from the original state
cloneNode(name, newStateNode, targetNodeRef, ctx);
}
// Change state for tmp node to allow delete it without special permission
String newStateNodeName = (String) nodeService.getProperty(newStateNode, ContentModel.PROP_NAME);
FileState stateForTmp = ctx.getStateCache().findFileState(newName.substring(0, newName.lastIndexOf("\\")) + "\\" + newStateNodeName, true);
stateForTmp.addAttribute(CanDeleteWithoutPerms, true);
stateForTmp.setFileStatus(FileStatus.FileExists);
stateForTmp.setExpiryTime(System.currentTimeMillis() + FileState.DeleteTimeout);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Set CanDeleteWithoutPerms=true for " + stateForTmp);
} else if (newState.getFileStatus() == DeleteOnClose) {
logger.debug("file state is delete on close");
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Restoring delete-on-close node, " + newState);
// Restore the deleted node so we can relink the new version to the old history/properties
NodeRef archivedNode = getNodeArchiveService().getArchivedNode((NodeRef) newState.getFilesystemObject());
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Found archived node " + archivedNode);
if (archivedNode != null && getNodeService().exists(archivedNode)) {
// Restore the node
targetNodeRef = getNodeService().restoreNode(archivedNode, null, null, null);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Restored node " + targetNodeRef + ", version=" + nodeService.getProperty(targetNodeRef, ContentModel.PROP_VERSION_LABEL));
// Check if the deleted file had a linked node, due to a rename
NodeRef linkNode = (NodeRef) newState.findAttribute(AttrLinkNode);
if (linkNode != null && nodeService.exists(linkNode)) {
// Clone aspects from the linked node onto the restored node
cloneNode(name, linkNode, targetNodeRef, ctx);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME)) {
logger.debug(" Moved aspects from linked node " + linkNode);
// Check if the node is a working copy
NodeRef mainNodeRef = checkOutCheckInService.getCheckedOut(targetNodeRef);
if (mainNodeRef != null) {
// Check if the main document is still locked
LockType lockTyp = lockService.getLockType(mainNodeRef);
logger.debug(" Main node ref lock type = " + lockTyp);
}
}
}
}
} else if (isFromVersionable == true) {
logger.debug("from node is versionable");
// Create a new node for the target
targetNodeRef = cifsHelper.createNode(ctx.getRootNode(), newName, nodeService.getType(nodeToMoveRef));
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Created new node for " + newName + ", isFromVersionable=true");
// Copy aspects from the original file
cloneNode(name, nodeToMoveRef, targetNodeRef, ctx);
// Change state for tmp node to allow delete it without special permission
FileState stateForTmp = ctx.getStateCache().findFileState(newName, true);
stateForTmp.addAttribute(CanDeleteWithoutPerms, true);
stateForTmp.setFileStatus(FileStatus.FileExists);
stateForTmp.setExpiryTime(System.currentTimeMillis() + FileState.DeleteTimeout);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Set CanDeleteWithoutPerms=true for " + stateForTmp);
}
}
// If the original or target nodes are not versionable and types are compatible then just use a standard rename of the node
if (!renameShuffle || (!isFromVersionable && typesCompatible && (targetNodeRef == null || nodeService.hasAspect(targetNodeRef, ContentModel.ASPECT_VERSIONABLE) == false))) {
logger.debug("do simple rename");
// Rename the file/folder
cifsHelper.rename(nodeToMoveRef, name);
postTxn.add(new Runnable() {
public void run() {
// Mark the new file as existing
newState.setFileStatus(FileExists);
newState.setFilesystemObject(nodeToMoveRef);
newState.setFileSize(oldState.getFileSize());
// the date is updated to be properly saved when the document is closed, see MNT-214
newState.updateModifyDateTime(oldState.getModifyDateTime());
// Make sure the old file state is cached for a short while, the file may not be open so the
// file state could be expired
oldState.setExpiryTime(System.currentTimeMillis() + FileState.DeleteTimeout);
// Indicate that this is a renamed file state, set the node ref of the file that was renamed
oldState.setFileStatus(FileRenamed);
oldState.setFilesystemObject(nodeToMoveRef);
}
});
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Use standard rename for " + name + "(versionable=" + isFromVersionable + ", targetNodeRef=" + targetNodeRef + ")");
} else {
if (targetNodeRef == null) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" No target node for rename");
throw new AccessDeniedException("No target node for file rename");
}
// Copy content data from the old file to the new file
copyContentData(sess, tree, nodeToMoveRef, targetNodeRef, newName);
final NodeRef finalTargetNodeRef = targetNodeRef;
postTxn.add(new Runnable() {
public void run() {
// Mark the new file as existing
newState.setFileStatus(FileExists);
newState.setFilesystemObject(finalTargetNodeRef);
newState.setFileSize(oldState.getFileSize());
// the date is updated to be properly saved when the document is closed, see MNT-214
newState.updateModifyDateTime(oldState.getModifyDateTime());
// Make sure the old file state is cached for a short while, the file may not be open so the
// file state could be expired
oldState.setExpiryTime(System.currentTimeMillis() + FileState.DeleteTimeout);
// Indicate that this is a deleted file state, set the node ref of the file that was renamed
oldState.setFileStatus(DeleteOnClose);
oldState.setFilesystemObject(nodeToMoveRef);
// Link to the new node, a new file may be renamed into place, we need to transfer aspect/locks
oldState.addAttribute(AttrLinkNode, finalTargetNodeRef);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Cached delete state for " + oldName);
}
});
logger.debug("delete the old file");
// Delete the old file
if (renameShuffle && isFromVersionable && permissionService.hasPermission(nodeToMoveRef, PermissionService.EDITOR) == AccessStatus.ALLOWED) {
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>() {
@Override
public Object doWork() throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("Rename shuffle for versioning content is assumed. Deleting " + nodeToMoveRef + " as system user");
}
if (renameCSVShufflePattern.matcher(newName.toLowerCase()).matches()) {
Map<QName, Serializable> props = Collections.emptyMap();
nodeService.addAspect(nodeToMoveRef, ContentModel.ASPECT_SOFT_DELETE, props);
} else {
nodeService.deleteNode(nodeToMoveRef);
}
return null;
}
}, AuthenticationUtil.getSystemUserName());
} else {
if (logger.isDebugEnabled()) {
logger.debug("Deleting " + nodeToMoveRef + " as user: " + AuthenticationUtil.getFullyAuthenticatedUser());
}
nodeService.deleteNode(nodeToMoveRef);
}
}
return postTxn;
}
});
logger.debug("running post txns");
// Run the required state-changing logic once the retrying transaction has completed successfully
for (Runnable runnable : postTxn) {
runnable.run();
}
}
} catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename file - access denied, " + oldName);
throw new AccessDeniedException("Rename file " + oldName);
} catch (NodeLockedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename file", ex);
throw new AccessDeniedException("Node locked " + oldName);
} catch (InvalidNodeRefException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename file - file doesn't exist, " + oldName, ex);
throw new FileNotFoundException("File doesn't exist " + oldName);
} catch (RuntimeException ex) {
// Unexpected Exception being consumed here - hence the error logging.
logger.error("Unable to rename file" + oldName, ex);
throw new AccessDeniedException("Rename file " + oldName);
}
}
use of org.alfresco.jlan.server.filesys.cache.FileState in project alfresco-repository by Alfresco.
the class ContentDiskDriver method deleteFile.
/**
* Delete the specified file.
*
* @param sess Server session
* @param tree Tree connection
* @param name NetworkFile
* @exception java.io.IOException The exception description.
*/
public void deleteFile(final SrvSession sess, final TreeConnection tree, final String name) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("Delete file - " + name);
}
final ContentContext ctx = (ContentContext) tree.getContext();
try {
// Check if there is a quota manager enabled, if so then we need to save the current file size
final QuotaManager quotaMgr = ctx.getQuotaManager();
// Perform repository updates in a retryable write transaction
Callable<Void> postTxn = doInWriteTransaction(sess, new CallableIO<Callable<Void>>() {
public Callable<Void> call() throws IOException {
// Get the node and delete it
final NodeRef nodeRef = getNodeForPath(tree, name);
Callable<Void> result = null;
if (fileFolderService.exists(nodeRef)) {
// Get the size of the file being deleted
final FileInfo fInfo = quotaMgr == null ? null : getFileInformation(sess, tree, name);
// Check if the node is versionable
final boolean isVersionable = nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE);
if (logger.isDebugEnabled()) {
logger.debug("deleted file" + name);
}
fileFolderService.delete(nodeRef);
// Return the operations to perform when the transaction succeeds
result = new Callable<Void>() {
public Void call() throws Exception {
if (ctx.hasStateCache()) {
if (isVersionable == true) {
// Make sure the file state is cached for a short while, a new file may be
// renamed to the same name
// in which case we can connect the file to the previous version history
FileState delState = ctx.getStateCache().findFileState(name, true);
if (logger.isDebugEnabled()) {
logger.debug("set delete on close" + name);
}
delState.setExpiryTime(System.currentTimeMillis() + FileState.DeleteTimeout);
delState.setFileStatus(DeleteOnClose);
delState.setFilesystemObject(nodeRef);
} else {
// Remove the file state
ctx.getStateCache().removeFileState(name);
}
// Update, or create, a parent folder file state
String[] paths = FileName.splitPath(name);
if (paths[0] != null && paths[0].length() > 1) {
// Get the file state for the parent folder
FileState parentState = getStateForPath(tree, paths[0]);
if (parentState == null && ctx.hasStateCache())
parentState = ctx.getStateCache().findFileState(paths[0], true);
// Update the modification timestamp
parentState.updateModifyDateTime();
}
}
if (quotaMgr != null)
quotaMgr.releaseSpace(sess, tree, fInfo.getFileId(), name, fInfo.getSize());
return null;
}
};
}
if (logger.isDebugEnabled() && (ctx.hasDebug(AlfrescoContext.DBG_FILE) || ctx.hasDebug(AlfrescoContext.DBG_RENAME)))
logger.debug("Deleted file: " + name + ", node=" + nodeRef);
return result;
}
});
// Perform state updates after the transaction succeeds
postTxn.call();
} catch (NodeLockedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete file - access denied (locked)");
throw new AccessDeniedException("Delete " + name);
} catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete file - access denied");
throw new AccessDeniedException("Delete " + name);
} catch (IOException ex) {
// Allow I/O Exceptions to pass through
throw ex;
} catch (Exception ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete file error", ex);
// Convert to a general I/O exception
IOException ioe = new IOException("Delete file " + name);
ioe.initCause(ex);
throw ioe;
}
}
use of org.alfresco.jlan.server.filesys.cache.FileState in project alfresco-repository by Alfresco.
the class ContentDiskDriver method deleteDirectory.
/**
* Delete the directory from the filesystem.
*
* @param sess Server session
* @param tree Tree connection
* @param dir Directory name.
* @exception java.io.IOException The exception description.
*/
public void deleteDirectory(SrvSession sess, TreeConnection tree, final String dir) throws IOException {
// get the device root
ContentContext ctx = (ContentContext) tree.getContext();
final NodeRef deviceRootNodeRef = ctx.getRootNode();
try {
NodeRef nodeRef = doInWriteTransaction(sess, new CallableIO<NodeRef>() {
public NodeRef call() throws IOException {
// Get the node for the folder
NodeRef nodeRef = cifsHelper.getNodeRef(deviceRootNodeRef, dir);
if (fileFolderService.exists(nodeRef)) {
if (cifsHelper.isFolderEmpty(nodeRef)) {
// Delete the folder node
fileFolderService.delete(nodeRef);
return nodeRef;
} else {
throw new DirectoryNotEmptyException(dir);
}
}
return null;
}
});
if (nodeRef != null && ctx.hasStateCache()) {
// Remove the file state
ctx.getStateCache().removeFileState(dir);
// Update, or create, a parent folder file state
String[] paths = FileName.splitPath(dir);
if (paths[0] != null && paths[0].length() > 1) {
// Get the file state for the parent folder
FileState parentState = getStateForPath(tree, paths[0]);
if (parentState == null && ctx.hasStateCache())
parentState = ctx.getStateCache().findFileState(paths[0], true);
// Update the modification timestamp
parentState.updateModifyDateTime();
}
}
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Deleted directory: directory=" + dir + " node=" + nodeRef);
} catch (FileNotFoundException e) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete directory - file not found, " + dir);
} catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete directory - access denied, " + dir);
throw new AccessDeniedException("Delete directory " + dir);
} catch (RuntimeException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete directory", ex);
throw new IOException("Delete directory " + dir);
}
}
use of org.alfresco.jlan.server.filesys.cache.FileState in project alfresco-repository by Alfresco.
the class ContentDiskDriver method getFileInformation.
/**
* Get the file information for the specified file.
*
* @param session Server session
* @param tree Tree connection
* @param path File name/path that information is required for.
* @return File information if valid, else null
* @exception java.io.IOException The exception description.
*/
public FileInfo getFileInformation(SrvSession session, TreeConnection tree, String path) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("getFileInformation:" + path);
}
// Start a transaction
beginReadTransaction(session);
// Get the device root
ContentContext ctx = (ContentContext) tree.getContext();
NodeRef infoParentNodeRef = ctx.getRootNode();
if (path == null || path.length() == 0)
path = FileName.DOS_SEPERATOR_STR;
String infoPath = path;
try {
// Check if the path is to a pseudo file
FileInfo finfo = null;
// Get the node ref for the path, chances are there is a file state in the cache
NodeRef nodeRef = getNodeForPath(tree, infoPath);
if (nodeRef != null) {
// Get the file information for the node
finfo = cifsHelper.getFileInformation(nodeRef, isReadOnly, isLockedFilesAsOffline);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("getInfo using cached noderef for path " + path);
}
if (finfo == null) {
String[] paths = FileName.splitPath(path);
if (paths[0] != null && paths[0].length() > 1) {
// Find the node ref for the folder being searched
nodeRef = getNodeForPath(tree, paths[0]);
if (nodeRef != null) {
infoParentNodeRef = nodeRef;
infoPath = paths[1];
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("getInfo using cached noderef for parent " + path);
}
}
// Access the repository to get the file information
finfo = cifsHelper.getFileInformation(infoParentNodeRef, infoPath, isReadOnly, isLockedFilesAsOffline);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Getting file information: path=" + path + " file info: " + finfo);
}
if (finfo != null) {
// Set the file id
long id = DefaultTypeConverter.INSTANCE.convert(Long.class, nodeService.getProperty(nodeRef, ContentModel.PROP_NODE_DBID));
finfo.setFileId((int) (id & 0xFFFFFFFFL));
// Copy cached file details, if available
FileState fstate = getStateForPath(tree, infoPath);
if (fstate != null) {
// finfo.setAccessDateTime(fstate.getAccessDateTime());
if (fstate.hasChangeDateTime())
finfo.setChangeDateTime(fstate.getChangeDateTime());
if (fstate.hasModifyDateTime())
finfo.setModifyDateTime(fstate.getModifyDateTime());
if (fstate.hasAllocationSize() && fstate.getAllocationSize() > finfo.getSize())
finfo.setAllocationSize(fstate.getAllocationSize());
} else {
// Create a file state for the file/folder
fstate = ctx.getStateCache().findFileState(path, true);
if (finfo.isDirectory())
fstate.setFileStatus(DirectoryExists);
else
fstate.setFileStatus(FileExists);
fstate.setFilesystemObject(nodeRef);
}
}
return finfo;
} catch (FileNotFoundException e) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Get file info - file not found, " + path);
throw e;
} catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Get file info - access denied, " + path);
throw new AccessDeniedException("Get file information " + path);
} catch (RuntimeException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Get file info error", ex);
throw new IOException("Get file information " + path);
}
}
use of org.alfresco.jlan.server.filesys.cache.FileState in project alfresco-repository by Alfresco.
the class BufferedContentDiskDriver method getFileInformation.
@Override
public FileInfo getFileInformation(SrvSession sess, TreeConnection tree, String path) throws IOException {
ContentContext tctx = (ContentContext) tree.getContext();
FileInfo info = getFileInformationInternal(sess, tree, path);
/*
* Some information is not maintained by the repo and represents an in-progress update.
* For example as a file is being written the modification and access dates change.
*/
if (tctx.hasStateCache()) {
FileStateCache cache = tctx.getStateCache();
FileState fstate = cache.findFileState(path, false);
if (fstate != null) {
if (logger.isDebugEnabled()) {
logger.debug("state cache available - overwriting from state cache: isDirectory=" + info.isDirectory());
}
FileInfo finfo = new FileInfo();
finfo.copyFrom(info);
/**
* File state is probably stale for directories which is why we don't attempt to
* cache.
*/
if (!info.isDirectory()) {
/*
* What about stale file state values 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()) {
if (logger.isDebugEnabled()) {
logger.debug("replace allocation size" + finfo.getAllocationSize() + " with " + fstate.getAllocationSize());
}
finfo.setAllocationSize(fstate.getAllocationSize());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Return getFileInformation, path: " + path + ", returning:" + finfo + ", readOnly:" + finfo.isReadOnly() + ", fileId:" + finfo.getFileId() + ", fileSize:" + finfo.getSize() + ", directoryId:" + finfo.getDirectoryId() + ", createdDate: " + new Date(finfo.getCreationDateTime()) + ", accessDate:" + new Date(finfo.getAccessDateTime()) + ", modifiedDate:" + new Date(finfo.getModifyDateTime()) + ", changeDate:" + new Date(finfo.getChangeDateTime()) + ", fileAttributes: 0x" + Integer.toHexString(info.getFileAttributes()) + ", mode: 0x" + Integer.toHexString(finfo.getMode()));
}
return finfo;
}
}
if (logger.isDebugEnabled()) {
logger.debug("getFileInformation Return:" + path + " returning" + info);
}
return info;
}
Aggregations