use of org.alfresco.jlan.server.filesys.cache.FileState in project alfresco-repository by Alfresco.
the class ContentDiskDriver method startSearch.
/**
* Start a new search on the filesystem using the specified searchPath that may contain
* wildcards.
*
* @param sess Server session
* @param tree Tree connection
* @param searchPath File(s) to search for, may include wildcards.
* @param attributes Attributes of the file(s) to search for, see class SMBFileAttribute.
* @return SearchContext
* @exception java.io.FileNotFoundException If the search could not be started.
*/
public SearchContext startSearch(SrvSession sess, TreeConnection tree, String searchPath, int attributes) throws FileNotFoundException {
// Access the device context
if (logger.isDebugEnabled()) {
logger.debug("startSearch: " + searchPath);
}
ContentContext ctx = (ContentContext) tree.getContext();
try {
String searchFileSpec = searchPath;
NodeRef searchRootNodeRef = ctx.getRootNode();
FileState searchFolderState = null;
// Create the transaction
beginReadTransaction(sess);
// If the state table is available see if we can speed up the search using either cached
// file information or find the folder node to be searched without having to walk the path
String[] paths = FileName.splitPath(searchPath);
if (ctx.hasStateCache()) {
if (paths[0] != null && paths[0].length() >= 1) {
// Find the node ref for the folder being searched
NodeRef nodeRef = getNodeForPath(tree, paths[0]);
// Get the file state for the folder being searched
searchFolderState = getStateForPath(tree, paths[0]);
if (searchFolderState == null) {
// Create a file state for the folder
searchFolderState = ctx.getStateCache().findFileState(paths[0], true);
}
if (searchFolderState.hasFilesystemObject() == false) {
// Set the associated node for the folder
searchFolderState.setFilesystemObject(nodeRef);
}
if (nodeRef != null) {
searchRootNodeRef = nodeRef;
searchFileSpec = paths[1];
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
logger.debug("Search using cached noderef for path " + searchPath);
}
}
}
if (searchFileSpec.equals("*.*"))
searchFileSpec = "*";
// Debug
long startTime = 0L;
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
startTime = System.currentTimeMillis();
// Perform the search
List<NodeRef> results = cifsHelper.getNodeRefs(searchRootNodeRef, searchFileSpec);
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH)) {
long endTime = System.currentTimeMillis();
if ((endTime - startTime) > 500)
logger.debug("Search for searchPath=" + searchPath + ", searchSpec=" + searchFileSpec + ", searchRootNode=" + searchRootNodeRef + " took " + (endTime - startTime) + "ms results=" + results.size());
}
// Build the search context to store the results, use the cache lookup search for wildcard searches
SearchContext searchCtx = null;
if (searchFileSpec.equals("*")) {
// Use a cache lookup search context
CacheLookupSearchContext cacheContext = new CacheLookupSearchContext(cifsHelper, results, searchFileSpec, paths[0], ctx.getStateCache(), isLockedFilesAsOffline);
searchCtx = cacheContext;
if (searchFolderState != null && searchFolderState.hasFilesystemObject()) {
// Get the '.' pseudo entry file details
FileInfo finfo = cifsHelper.getFileInformation((NodeRef) searchFolderState.getFilesystemObject(), isReadOnly, isLockedFilesAsOffline);
if (searchFolderState != null) {
if (searchFolderState.hasAccessDateTime())
finfo.setAccessDateTime(searchFolderState.getAccessDateTime());
if (searchFolderState.hasChangeDateTime())
finfo.setChangeDateTime(searchFolderState.getChangeDateTime());
if (searchFolderState.hasModifyDateTime())
finfo.setModifyDateTime(searchFolderState.getModifyDateTime());
}
// Set the '.' pseudo entry details
cacheContext.setDotInfo(finfo);
if (searchFolderState.getPath().equals(FileName.DOS_SEPERATOR_STR)) {
// Searching the root folder, re-use the search folder file information for the '..' pseudo entry
FileInfo dotDotInfo = new FileInfo();
dotDotInfo.copyFrom(finfo);
cacheContext.setDotDotInfo(dotDotInfo);
} else {
// Get the parent folder path
String parentPath = searchFolderState.getPath();
if (parentPath.endsWith(FileName.DOS_SEPERATOR_STR) && parentPath.length() > 1)
parentPath = parentPath.substring(0, parentPath.length() - 1);
int pos = parentPath.lastIndexOf(FileName.DOS_SEPERATOR_STR);
if (pos != -1)
parentPath = parentPath.substring(0, pos + 1);
// Get the file state for the parent path, if available
FileState parentState = ctx.getStateCache().findFileState(parentPath);
NodeRef parentNode = null;
if (parentState != null)
parentNode = (NodeRef) parentState.getFilesystemObject();
if (parentState == null || parentNode == null)
parentNode = getNodeForPath(tree, parentPath);
// Get the file information for the parent folder
finfo = cifsHelper.getFileInformation(parentNode, isReadOnly, isLockedFilesAsOffline);
if (parentState != null) {
if (parentState.hasAccessDateTime())
finfo.setAccessDateTime(parentState.getAccessDateTime());
if (parentState.hasChangeDateTime())
finfo.setChangeDateTime(parentState.getChangeDateTime());
if (parentState.hasModifyDateTime())
finfo.setModifyDateTime(parentState.getModifyDateTime());
}
// Set the '..' pseudo entry details
cacheContext.setDotDotInfo(finfo);
}
}
} else {
if (ctx.hasStateCache())
searchCtx = new CacheLookupSearchContext(cifsHelper, results, searchFileSpec, paths[0], ctx.getStateCache(), isLockedFilesAsOffline);
else
searchCtx = new ContentSearchContext(cifsHelper, results, searchFileSpec, paths[0], isLockedFilesAsOffline);
}
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
logger.debug("Started search: search path=" + searchPath + " attributes=" + attributes + ", ctx=" + searchCtx);
return searchCtx;
} catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
logger.debug("Start search - access denied, " + searchPath);
throw new FileNotFoundException("Start search " + searchPath);
} catch (RuntimeException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
logger.debug("Start search", ex);
throw new FileNotFoundException("Start search " + searchPath);
}
}
use of org.alfresco.jlan.server.filesys.cache.FileState in project alfresco-repository by Alfresco.
the class ContentDiskDriver method setFileInformation.
/**
* Set file information
*
* @param sess SrvSession
* @param tree TreeConnection
* @param name String
* @param info FileInfo
* @exception IOException
*/
public void setFileInformation(SrvSession sess, final TreeConnection tree, final String name, final FileInfo info) throws IOException {
// Get the device context
final ContentContext ctx = (ContentContext) tree.getContext();
try {
final FileState fstate = getStateForPath(tree, name);
doInWriteTransaction(sess, new CallableIO<Pair<Boolean, Boolean>>() {
public Pair<Boolean, Boolean> call() throws IOException {
// Get the file/folder node
NodeRef nodeRef = getNodeForPath(tree, name);
if (permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED) {
throw new AccessDeniedException("No write access to " + name);
}
// Inhibit versioning for this transaction
getPolicyFilter().disableBehaviour(ContentModel.ASPECT_VERSIONABLE);
if (info.hasSetFlag(FileInfo.SetDeleteOnClose) && info.hasDeleteOnClose()) {
// Check deleting permissions on the node if action of deleting was configured only
if ((AccessStatus.DENIED == permissionService.hasPermission(nodeRef, PermissionService.DELETE)) && ((null == fstate) || (null == fstate.findAttribute(CanDeleteWithoutPerms)))) {
throw new org.alfresco.repo.security.permissions.AccessDeniedException("No delete access to " + name);
}
if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE)) {
// Get the lock type, if any
String lockTypeStr = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_LOCK_TYPE);
if (lockTypeStr != null)
throw new org.alfresco.repo.security.permissions.AccessDeniedException("Node locked, cannot mark for delete");
}
if (fileFolderService.exists(nodeRef)) {
// Check if it is a folder that is being deleted, make sure it is empty
boolean isFolder = true;
if (fstate != null)
isFolder = fstate.isDirectory();
else {
ContentFileInfo cInfo = cifsHelper.getFileInformation(nodeRef, isReadOnly, isLockedFilesAsOffline);
if (cInfo != null && cInfo.isDirectory() == false)
isFolder = false;
}
if (isFolder == true && cifsHelper.isFolderEmpty(nodeRef) == false)
throw new DirectoryNotEmptyException(name);
}
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Set deleteOnClose=true file=" + name);
}
// Set the creation and modified date/time
Map<QName, Serializable> auditableProps = new HashMap<QName, Serializable>(5);
if (info.hasSetFlag(FileInfo.SetCreationDate)) {
// Set the creation date on the file/folder node
Date createDate = new Date(info.getCreationDateTime());
auditableProps.put(ContentModel.PROP_CREATED, 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);
}
// Did we have any cm:auditable properties?
if (auditableProps.size() > 0) {
getPolicyFilter().disableBehaviour(nodeRef, ContentModel.ASPECT_AUDITABLE);
nodeService.addProperties(nodeRef, auditableProps);
// DEBUG
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Set auditable props: " + auditableProps + " file=" + name);
}
return null;
}
});
// Update the change date/time
if (fstate != null) {
if (info.hasSetFlag(FileInfo.SetDeleteOnClose) && info.hasDeleteOnClose() || info.hasSetFlag(FileInfo.SetCreationDate)) {
fstate.updateChangeDateTime();
}
if (info.hasSetFlag(FileInfo.SetModifyDate)) {
// Update the change date/time, clear the cached modification date/time
fstate.updateChangeDateTime();
Date modifyDate = new Date(info.getModifyDateTime());
fstate.updateModifyDateTime(modifyDate.getTime());
}
}
} catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Set file information - access denied, " + name, ex);
throw new AccessDeniedException("Set file information " + name);
} catch (RuntimeException ex) {
if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Open file error", ex);
throw new IOException("Set file information " + name);
}
}
use of org.alfresco.jlan.server.filesys.cache.FileState in project alfresco-repository by Alfresco.
the class CacheLookupSearchContext method nextFileInfo.
/**
* Return file information for the next file in the active search. Returns false if the search
* is complete.
*
* @param info FileInfo to return the file information.
* @return true if the file information is valid, else false
*/
public boolean nextFileInfo(FileInfo info) {
if (super.nextFileInfo(info) == false)
return false;
// We have a real file entry, check if there is a cache entry
StringBuilder relPath = new StringBuilder(getRelativePath());
relPath.append(info.getFileName());
FileState fstate = m_stateCache.findFileState(relPath.toString());
if (fstate != null) {
if (fstate.hasAccessDateTime())
info.setAccessDateTime(fstate.getAccessDateTime());
if (fstate.hasModifyDateTime())
info.setModifyDateTime(fstate.getModifyDateTime());
if (fstate.hasFileSize())
info.setFileSize(fstate.getFileSize());
if (fstate.hasAllocationSize() && fstate.getAllocationSize() > info.getSize())
info.setAllocationSize(fstate.getAllocationSize());
if (logger.isDebugEnabled())
logger.debug("Search timestamps from cache, path=" + info.getFileName());
}
return true;
}
Aggregations