mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Added AVM callback handlers to update the virtualization view pseudo folders when stores/versions are created or purged.
The callback handlers queue change notifications so Windows Explorer views that are open on a pseudo folder should update (most of the time). git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4595 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -20,7 +20,17 @@ package org.alfresco.filesys.avm;
|
||||
import org.alfresco.filesys.alfresco.AlfrescoContext;
|
||||
import org.alfresco.filesys.alfresco.IOControlHandler;
|
||||
import org.alfresco.filesys.server.filesys.DiskInterface;
|
||||
import org.alfresco.filesys.server.filesys.FileName;
|
||||
import org.alfresco.filesys.server.filesys.FileSystem;
|
||||
import org.alfresco.filesys.server.filesys.NotifyChange;
|
||||
import org.alfresco.filesys.server.state.FileState;
|
||||
import org.alfresco.filesys.server.state.FileStateTable;
|
||||
import org.alfresco.repo.avm.CreateStoreCallback;
|
||||
import org.alfresco.repo.avm.CreateVersionCallback;
|
||||
import org.alfresco.repo.avm.PurgeStoreCallback;
|
||||
import org.alfresco.repo.avm.PurgeVersionCallback;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* AVM Filesystem Context Class
|
||||
@@ -29,8 +39,13 @@ import org.alfresco.filesys.server.filesys.FileSystem;
|
||||
*
|
||||
* @author GKSpencer
|
||||
*/
|
||||
public class AVMContext extends AlfrescoContext {
|
||||
public class AVMContext extends AlfrescoContext
|
||||
implements CreateStoreCallback, PurgeStoreCallback, CreateVersionCallback, PurgeVersionCallback {
|
||||
|
||||
// Logging
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AVMContext.class);
|
||||
|
||||
// Constants
|
||||
//
|
||||
// Version id that indicates the head version
|
||||
@@ -149,4 +164,226 @@ public class AVMContext extends AlfrescoContext {
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create store call back handler
|
||||
*
|
||||
* @param storeName String
|
||||
* @param versionID int
|
||||
*/
|
||||
public void storeCreated(String storeName)
|
||||
{
|
||||
// Make sure the file state cache is enabled
|
||||
|
||||
FileStateTable fsTable = getStateTable();
|
||||
if ( fsTable == null)
|
||||
return;
|
||||
|
||||
// Find the file state for the root folder
|
||||
|
||||
FileState rootState = fsTable.findFileState( FileName.DOS_SEPERATOR_STR);
|
||||
|
||||
if ( rootState != null && rootState.hasPseudoFiles())
|
||||
{
|
||||
// Add a pseudo folder for the new store
|
||||
|
||||
rootState.addPseudoFile( new StorePseudoFile( storeName));
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug( "Added pseudo folder for new store " + storeName);
|
||||
|
||||
// Send a change notification for the new folder
|
||||
|
||||
if ( hasChangeHandler())
|
||||
{
|
||||
// Build the filesystem relative path to the new store folder
|
||||
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
str.append( FileName.DOS_SEPERATOR);
|
||||
str.append( storeName);
|
||||
|
||||
// Send the change notification
|
||||
|
||||
getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionAdded, str.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge store call back handler
|
||||
*
|
||||
* @param storeName String
|
||||
*/
|
||||
public void storePurged(String storeName)
|
||||
{
|
||||
// Make sure the file state cache is enabled
|
||||
|
||||
FileStateTable fsTable = getStateTable();
|
||||
if ( fsTable == null)
|
||||
return;
|
||||
|
||||
// Find the file state for the root folder
|
||||
|
||||
FileState rootState = fsTable.findFileState( FileName.DOS_SEPERATOR_STR);
|
||||
if ( rootState != null && rootState.hasPseudoFiles())
|
||||
{
|
||||
// Remove the pseudo folder for the store
|
||||
|
||||
rootState.getPseudoFileList().removeFile( storeName, false);
|
||||
|
||||
// Build the filesystem relative path to the deleted store folder
|
||||
|
||||
StringBuilder pathStr = new StringBuilder();
|
||||
|
||||
pathStr.append( FileName.DOS_SEPERATOR);
|
||||
pathStr.append( storeName);
|
||||
|
||||
// Remove the file state for the deleted store
|
||||
|
||||
String storePath = pathStr.toString();
|
||||
fsTable.removeFileState( storePath);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug( "Removed pseudo folder for purged store " + storeName);
|
||||
|
||||
// Send a change notification for the deleted folder
|
||||
|
||||
if ( hasChangeHandler())
|
||||
{
|
||||
// Send the change notification
|
||||
|
||||
getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionRemoved, storePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create version call back handler
|
||||
*
|
||||
* @param storeName String
|
||||
* @param versionID int
|
||||
*/
|
||||
public void versionCreated(String storeName, int versionID)
|
||||
{
|
||||
// Make sure the file state cache is enabled
|
||||
|
||||
FileStateTable fsTable = getStateTable();
|
||||
if ( fsTable == null)
|
||||
return;
|
||||
|
||||
// Build the path to the store version folder
|
||||
|
||||
StringBuilder pathStr = new StringBuilder();
|
||||
|
||||
pathStr.append( FileName.DOS_SEPERATOR);
|
||||
pathStr.append( storeName);
|
||||
pathStr.append( FileName.DOS_SEPERATOR);
|
||||
pathStr.append( AVMPath.VersionsFolder);
|
||||
|
||||
// Find the file state for the store versions folder
|
||||
|
||||
FileState verState = fsTable.findFileState( pathStr.toString());
|
||||
|
||||
if ( verState != null && verState.hasPseudoFiles())
|
||||
{
|
||||
// Create the version folder name
|
||||
|
||||
StringBuilder verStr = new StringBuilder();
|
||||
|
||||
verStr.append( AVMPath.VersionFolderPrefix);
|
||||
verStr.append( versionID);
|
||||
|
||||
String verName = verStr.toString();
|
||||
|
||||
// Add a pseudo folder for the new version
|
||||
|
||||
verState.addPseudoFile( new VersionPseudoFile( verName));
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug( "Added pseudo folder for new version " + storeName + ":/" + verName);
|
||||
|
||||
// Send a change notification for the new folder
|
||||
|
||||
if ( hasChangeHandler())
|
||||
{
|
||||
// Build the filesystem relative path to the new version folder
|
||||
|
||||
pathStr.append( FileName.DOS_SEPERATOR);
|
||||
pathStr.append( verName);
|
||||
|
||||
// Send the change notification
|
||||
|
||||
getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionAdded, pathStr.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge version call back handler
|
||||
*
|
||||
* @param storeName String
|
||||
*/
|
||||
public void versionPurged(String storeName, int versionID)
|
||||
{
|
||||
// Make sure the file state cache is enabled
|
||||
|
||||
FileStateTable fsTable = getStateTable();
|
||||
if ( fsTable == null)
|
||||
return;
|
||||
|
||||
// Build the path to the store version folder
|
||||
|
||||
StringBuilder pathStr = new StringBuilder();
|
||||
|
||||
pathStr.append( FileName.DOS_SEPERATOR);
|
||||
pathStr.append( storeName);
|
||||
pathStr.append( FileName.DOS_SEPERATOR);
|
||||
pathStr.append( AVMPath.VersionsFolder);
|
||||
|
||||
// Find the file state for the store versions folder
|
||||
|
||||
FileState verState = fsTable.findFileState( pathStr.toString());
|
||||
|
||||
if ( verState != null && verState.hasPseudoFiles())
|
||||
{
|
||||
// Create the version folder name
|
||||
|
||||
StringBuilder verStr = new StringBuilder();
|
||||
|
||||
verStr.append( AVMPath.VersionFolderPrefix);
|
||||
verStr.append( versionID);
|
||||
|
||||
String verName = verStr.toString();
|
||||
|
||||
// Remove the pseudo folder for the purged version
|
||||
|
||||
verState.getPseudoFileList().removeFile( verName, true);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug( "Removed pseudo folder for purged version " + storeName + ":/" + verName);
|
||||
|
||||
// Send a change notification for the deleted folder
|
||||
|
||||
if ( hasChangeHandler())
|
||||
{
|
||||
// Build the filesystem relative path to the deleted version folder
|
||||
|
||||
pathStr.append( FileName.DOS_SEPERATOR);
|
||||
pathStr.append( verName);
|
||||
|
||||
// Send the change notification
|
||||
|
||||
getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionRemoved, pathStr.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -50,6 +50,10 @@ import org.alfresco.filesys.server.pseudo.PseudoFolderNetworkFile;
|
||||
import org.alfresco.filesys.server.state.FileState;
|
||||
import org.alfresco.filesys.util.StringList;
|
||||
import org.alfresco.filesys.util.WildCard;
|
||||
import org.alfresco.repo.avm.CreateStoreTxnListener;
|
||||
import org.alfresco.repo.avm.CreateVersionTxnListener;
|
||||
import org.alfresco.repo.avm.PurgeStoreTxnListener;
|
||||
import org.alfresco.repo.avm.PurgeVersionTxnListener;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.service.cmr.avm.AVMExistsException;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
@@ -97,6 +101,14 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
|
||||
private AuthenticationComponent m_authComponent;
|
||||
private AuthenticationService m_authService;
|
||||
|
||||
// AVM listeners
|
||||
|
||||
private CreateStoreTxnListener m_createStoreListener;
|
||||
private PurgeStoreTxnListener m_purgeStoreListener;
|
||||
|
||||
private CreateVersionTxnListener m_createVerListener;
|
||||
private PurgeVersionTxnListener m_purgeVerListener;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
@@ -184,6 +196,46 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
|
||||
m_mimetypeService = mimetypeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the create store listener
|
||||
*
|
||||
* @param createStoreListener CreateStoreTxnListener
|
||||
*/
|
||||
public void setCreateStoreListener(CreateStoreTxnListener createStoreListener)
|
||||
{
|
||||
m_createStoreListener = createStoreListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the purge store listener
|
||||
*
|
||||
* @param purgeStoreListener PurgeStoreTxnListener
|
||||
*/
|
||||
public void setPurgeStoreListener(PurgeStoreTxnListener purgeStoreListener)
|
||||
{
|
||||
m_purgeStoreListener = purgeStoreListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the create version listener
|
||||
*
|
||||
* @param createVersionListener CreateVersionTxnListener
|
||||
*/
|
||||
public void setCreateVersionListener(CreateVersionTxnListener createVersionListener)
|
||||
{
|
||||
m_createVerListener = createVersionListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the purge version listener
|
||||
*
|
||||
* @param purgeVersionListener PurgeVersionTxnListener
|
||||
*/
|
||||
public void setPurgeVersionListener(PurgeVersionTxnListener purgeVersionListener)
|
||||
{
|
||||
m_purgeVerListener = purgeVersionListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and validate the parameter string and create a device context object for this instance
|
||||
* of the shared device.
|
||||
@@ -248,6 +300,15 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
|
||||
rootState.addPseudoFile( new StorePseudoFile( storeDesc));
|
||||
}
|
||||
}
|
||||
|
||||
// Plug the virtualization view context into the various store/version call back listeners
|
||||
// so that store/version pseudo folders can be kept in sync with AVM
|
||||
|
||||
m_createStoreListener.addCallback( context);
|
||||
m_purgeStoreListener.addCallback( context);
|
||||
|
||||
m_createVerListener.addCallback( context);
|
||||
m_purgeVerListener.addCallback( context);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -51,6 +51,23 @@ public class StorePseudoFile extends PseudoFile {
|
||||
setFileInfo( fInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param storeName String
|
||||
*/
|
||||
public StorePseudoFile( String storeName)
|
||||
{
|
||||
super( storeName, FileAttribute.Directory + FileAttribute.ReadOnly);
|
||||
|
||||
// Create static file information from the store details
|
||||
|
||||
FileInfo fInfo = new FileInfo( storeName, 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
|
||||
fInfo.setCreationDateTime( System.currentTimeMillis());
|
||||
|
||||
setFileInfo( fInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a network file for reading/writing the pseudo file
|
||||
*
|
||||
|
Reference in New Issue
Block a user