From 4834c89f5aad34ef7a5467b454f237ee024cf14e Mon Sep 17 00:00:00 2001 From: Gary Spencer Date: Wed, 13 Dec 2006 15:40:34 +0000 Subject: [PATCH] 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 --- config/alfresco/network-protocol-context.xml | 17 +- .../org/alfresco/filesys/avm/AVMContext.java | 239 +++++++++++++++++- .../alfresco/filesys/avm/AVMDiskDriver.java | 61 +++++ .../alfresco/filesys/avm/StorePseudoFile.java | 17 ++ 4 files changed, 327 insertions(+), 7 deletions(-) diff --git a/config/alfresco/network-protocol-context.xml b/config/alfresco/network-protocol-context.xml index feaba63146..cd7c8b8328 100644 --- a/config/alfresco/network-protocol-context.xml +++ b/config/alfresco/network-protocol-context.xml @@ -60,8 +60,8 @@ - - + + @@ -76,13 +76,18 @@ - + - - - + + + + + + + + diff --git a/source/java/org/alfresco/filesys/avm/AVMContext.java b/source/java/org/alfresco/filesys/avm/AVMContext.java index aba6423260..7d9969a874 100644 --- a/source/java/org/alfresco/filesys/avm/AVMContext.java +++ b/source/java/org/alfresco/filesys/avm/AVMContext.java @@ -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()); + } + } + } } diff --git a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java index be57a7d08d..aba29be90e 100644 --- a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java +++ b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java @@ -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 { diff --git a/source/java/org/alfresco/filesys/avm/StorePseudoFile.java b/source/java/org/alfresco/filesys/avm/StorePseudoFile.java index d9097d59dd..e4fd345b3a 100644 --- a/source/java/org/alfresco/filesys/avm/StorePseudoFile.java +++ b/source/java/org/alfresco/filesys/avm/StorePseudoFile.java @@ -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 *