Updates to AVM virtualization view for the latest layout with DATA and METADATA folders.

Fixes to AVM filesystem transaction handling.
Made SrvSession.beginTransaction() private and added beginReadTransaction() and beginWriteTransaction().

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4580 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gary Spencer
2006-12-12 14:07:07 +00:00
parent 3e6468bd02
commit f2c5192a7f
15 changed files with 1474 additions and 315 deletions

View File

@@ -199,6 +199,14 @@ public class CIFSServer extends AbstractLifecycleBean
if ( srv != null) if ( srv != null)
srv.shutdownServer(true); srv.shutdownServer(true);
// Stop the NFS server, if running
server.getConfiguration().setNFSServerEnabled(false);
srv = server.getConfiguration().findServer("NFS");
if ( srv != null)
srv.shutdownServer(true);
// Only wait for shutdown if the SMB/CIFS server is enabled // Only wait for shutdown if the SMB/CIFS server is enabled
if ( server.getConfiguration().isSMBServerEnabled()) if ( server.getConfiguration().isSMBServerEnabled())

View File

@@ -523,10 +523,6 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Create a path for the virtualization view // Create a path for the virtualization view
avmPath = new AVMPath( path); avmPath = new AVMPath( path);
// Validate that the store and version, if specified
} }
else else
{ {
@@ -605,14 +601,14 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Check if the filesystem is the virtualization view // Check if the filesystem is the virtualization view
if ( ctx.isVirtualizationView() && storePath.isPseudoPath()) if ( ctx.isVirtualizationView() && storePath.isReadOnlyPseudoPath())
{ {
throw new AccessDeniedException( "Cannot create folder in store/version layer, " + params.getPath()); throw new AccessDeniedException( "Cannot create folder in store/version layer, " + params.getPath());
} }
// Create a new file // Create a new file
sess.beginTransaction( m_transactionService, false); sess.beginWriteTransaction( m_transactionService);
try try
{ {
@@ -649,8 +645,6 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Check if the filesystem is writable // Check if the filesystem is writable
AVMContext ctx = (AVMContext) tree.getContext(); AVMContext ctx = (AVMContext) tree.getContext();
if ( ctx.isVersion() != AVMContext.VERSION_HEAD)
throw new AccessDeniedException("Cannot create " + params.getPath() + ", filesys not writable");
// Split the path to get the file name and relative path // Split the path to get the file name and relative path
@@ -667,14 +661,18 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Check if the filesystem is the virtualization view // Check if the filesystem is the virtualization view
if ( ctx.isVirtualizationView() && storePath.isPseudoPath()) if ( ctx.isVirtualizationView() && storePath.isReadOnlyPseudoPath())
{ {
throw new AccessDeniedException( "Cannot create file in store/version layer, " + params.getPath()); throw new AccessDeniedException( "Cannot create file in store/version layer, " + params.getPath());
} }
else if ( storePath.getVersion() != AVMContext.VERSION_HEAD)
{
throw new AccessDeniedException("Cannot create " + params.getPath() + ", filesys not writable");
}
// Create a new file // Create a new file
sess.beginTransaction( m_transactionService, false); sess.beginWriteTransaction( m_transactionService);
AVMNetworkFile netFile = null; AVMNetworkFile netFile = null;
@@ -687,13 +685,13 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Get the new file details // Get the new file details
AVMPath fileStorePath = buildStorePath( ctx, params.getPath()); AVMPath fileStorePath = buildStorePath( ctx, params.getPath());
AVMNodeDescriptor nodeDesc = m_avmService.lookup( ctx.isVersion(), fileStorePath.getAVMPath()); AVMNodeDescriptor nodeDesc = m_avmService.lookup( fileStorePath.getVersion(), fileStorePath.getAVMPath());
if ( nodeDesc != null) if ( nodeDesc != null)
{ {
// Create the network file object for the new file // Create the network file object for the new file
netFile = new AVMNetworkFile( nodeDesc, fileStorePath.getAVMPath(), ctx.isVersion(), m_avmService); netFile = new AVMNetworkFile( nodeDesc, fileStorePath.getAVMPath(), fileStorePath.getVersion(), m_avmService);
netFile.setGrantedAccess(NetworkFile.READWRITE); netFile.setGrantedAccess(NetworkFile.READWRITE);
netFile.setFullName(params.getPath()); netFile.setFullName(params.getPath());
@@ -750,11 +748,11 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Make sure the path is to a folder before deleting it // Make sure the path is to a folder before deleting it
sess.beginTransaction( m_transactionService, false); sess.beginWriteTransaction( m_transactionService);
try try
{ {
AVMNodeDescriptor nodeDesc = m_avmService.lookup( ctx.isVersion(), storePath.getAVMPath()); AVMNodeDescriptor nodeDesc = m_avmService.lookup( storePath.getVersion(), storePath.getAVMPath());
if ( nodeDesc != null) if ( nodeDesc != null)
{ {
// Check that we are deleting a folder // Check that we are deleting a folder
@@ -815,11 +813,11 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Make sure the path is to a file before deleting it // Make sure the path is to a file before deleting it
sess.beginTransaction( m_transactionService, false); sess.beginWriteTransaction( m_transactionService);
try try
{ {
AVMNodeDescriptor nodeDesc = m_avmService.lookup( ctx.isVersion(), storePath.getAVMPath()); AVMNodeDescriptor nodeDesc = m_avmService.lookup( storePath.getVersion(), storePath.getAVMPath());
if ( nodeDesc != null) if ( nodeDesc != null)
{ {
// Check that we are deleting a file // Check that we are deleting a file
@@ -865,42 +863,52 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled())
logger.debug("File exists check, path=" + name + ", storePath=" + storePath); logger.debug("File exists check, path=" + name + ", storePath=" + storePath);
// Check if the filesystem is the virtualization view // Check if the path is valid
int status = FileStatus.NotExist; int status = FileStatus.NotExist;
if ( ctx.isVirtualizationView() && storePath.isPseudoPath()) if ( storePath.isValid() == false)
return status;
// Check if the filesystem is the virtualization view
if ( ctx.isVirtualizationView() && storePath.isReadOnlyPseudoPath())
{ {
// Check if the search path is for the root or a store folder // Find the file state for the pseudo folder
if ( storePath.isRootPath()) FileState fstate = findPseudoState( storePath, ctx);
if ( fstate != null)
{ {
return FileStatus.DirectoryExists; // DEBUG
}
else
{
// Get the pseudo file for the store/version folder
PseudoFile psFile = findPseudoFolder( storePath, ctx); if ( logger.isDebugEnabled())
if ( psFile != null) logger.debug( " Found pseudo file " + fstate);
{
// DEBUG
if ( logger.isDebugEnabled()) // Check if the pseudo file is a file or folder
logger.debug( " Found pseudo file " + psFile);
return FileStatus.DirectoryExists; if ( fstate.isDirectory())
} status = FileStatus.DirectoryExists;
else else
return FileStatus.NotExist; status = FileStatus.FileExists;
} }
else
{
// Invalid pseudo file path
status = FileStatus.NotExist;
}
// Return the file status
return status;
} }
// Search for the file/folder // Search for the file/folder
sess.beginTransaction( m_transactionService, true); sess.beginReadTransaction( m_transactionService);
AVMNodeDescriptor nodeDesc = m_avmService.lookup( ctx.isVersion(), storePath.getAVMPath()); AVMNodeDescriptor nodeDesc = m_avmService.lookup( storePath.getVersion(), storePath.getAVMPath());
if ( nodeDesc != null) if ( nodeDesc != null)
{ {
@@ -955,9 +963,14 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled())
logger.debug("Get file information, path=" + name + ", storePath=" + storePath); logger.debug("Get file information, path=" + name + ", storePath=" + storePath);
// Check if hte path is valid
if ( storePath.isValid() == false)
throw new FileNotFoundException( name);
// Check if the filesystem is the virtualization view // Check if the filesystem is the virtualization view
if ( ctx.isVirtualizationView() && storePath.isPseudoPath()) if ( ctx.isVirtualizationView() && storePath.isReadOnlyPseudoPath())
{ {
// Check if the search path is for the root, a store or version folder // Check if the search path is for the root, a store or version folder
@@ -965,7 +978,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
{ {
// Return dummy file informatiom for the root folder // Return dummy file informatiom for the root folder
return new FileInfo( name,0L, FileAttribute.Directory); return new FileInfo( name, 0L, FileAttribute.Directory);
} }
else else
{ {
@@ -981,13 +994,13 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
return psFile.getFileInfo(); return psFile.getFileInfo();
} }
else else
return null; throw new FileNotFoundException( name);
} }
} }
// Search for the file/folder // Search for the file/folder
sess.beginTransaction( m_transactionService, true); sess.beginReadTransaction( m_transactionService);
FileInfo info = null; FileInfo info = null;
@@ -1095,7 +1108,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Check if the filesystem is the virtualization view // Check if the filesystem is the virtualization view
if ( ctx.isVirtualizationView() && storePath.isPseudoPath()) if ( ctx.isVirtualizationView() && storePath.isReadOnlyPseudoPath())
{ {
// Check if the path is for the root, a store or version folder // Check if the path is for the root, a store or version folder
@@ -1125,7 +1138,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Search for the file/folder // Search for the file/folder
sess.beginTransaction( m_transactionService, true); sess.beginReadTransaction( m_transactionService);
AVMNetworkFile netFile = null; AVMNetworkFile netFile = null;
@@ -1133,20 +1146,20 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
{ {
// Get the details of the file/folder // Get the details of the file/folder
AVMNodeDescriptor nodeDesc = m_avmService.lookup( ctx.isVersion(), storePath.getAVMPath()); AVMNodeDescriptor nodeDesc = m_avmService.lookup( storePath.getVersion(), storePath.getAVMPath());
if ( nodeDesc != null) if ( nodeDesc != null)
{ {
// Check if the filesystem is read-only and write access has been requested // Check if the filesystem is read-only and write access has been requested
if ( ctx.isVersion() != AVMContext.VERSION_HEAD && ( params.isReadWriteAccess() || params.isWriteOnlyAccess())) if ( storePath.getVersion() != AVMContext.VERSION_HEAD && ( params.isReadWriteAccess() || params.isWriteOnlyAccess()))
throw new AccessDeniedException("File " + params.getPath() + " is read-only"); throw new AccessDeniedException("File " + params.getPath() + " is read-only");
// Create the network file object for the opened file/folder // Create the network file object for the opened file/folder
netFile = new AVMNetworkFile( nodeDesc, storePath.getAVMPath(), ctx.isVersion(), m_avmService); netFile = new AVMNetworkFile( nodeDesc, storePath.getAVMPath(), storePath.getVersion(), m_avmService);
if ( params.isReadOnlyAccess() || ctx.isVersion() != AVMContext.VERSION_HEAD) if ( params.isReadOnlyAccess() || storePath.getVersion() != AVMContext.VERSION_HEAD)
netFile.setGrantedAccess(NetworkFile.READONLY); netFile.setGrantedAccess(NetworkFile.READONLY);
else else
netFile.setGrantedAccess(NetworkFile.READWRITE); netFile.setGrantedAccess(NetworkFile.READWRITE);
@@ -1202,7 +1215,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
AVMNetworkFile avmFile = (AVMNetworkFile) file; AVMNetworkFile avmFile = (AVMNetworkFile) file;
if ( avmFile.hasContentChannel() == false) if ( avmFile.hasContentChannel() == false)
sess.beginTransaction( m_transactionService, true); sess.beginReadTransaction( m_transactionService);
// Read the file // Read the file
@@ -1252,14 +1265,14 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Check if the filesystem is the virtualization view // Check if the filesystem is the virtualization view
if ( ctx.isVirtualizationView() && oldAVMPath.isPseudoPath()) if ( ctx.isVirtualizationView() && oldAVMPath.isReadOnlyPseudoPath())
{ {
throw new AccessDeniedException( "Cannot rename folder in store/version layer, " + oldName); throw new AccessDeniedException( "Cannot rename folder in store/version layer, " + oldName);
} }
// Start a transaction for the rename // Start a transaction for the rename
sess.beginTransaction( m_transactionService, false); sess.beginWriteTransaction( m_transactionService);
try try
{ {
@@ -1304,7 +1317,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
AVMNetworkFile avmFile = (AVMNetworkFile) file; AVMNetworkFile avmFile = (AVMNetworkFile) file;
if ( avmFile.hasContentChannel() == false) if ( avmFile.hasContentChannel() == false)
sess.beginTransaction( m_transactionService, true); sess.beginReadTransaction( m_transactionService);
// Set the file position // Set the file position
@@ -1368,60 +1381,73 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Check if the filesystem is the virtualization view // Check if the filesystem is the virtualization view
if ( avmCtx.isVirtualizationView() && storePath.isPseudoPath()) if ( avmCtx.isVirtualizationView())
{ {
// Check if the search path is for the root or a store folder // Check for a search of a pseudo folder
FileState fstate = findPseudoState( storePath, avmCtx); if (storePath.isReadOnlyPseudoPath())
{
// Get the file state for the folder being searched
if ( fstate != null) FileState fstate = findPseudoState( storePath, avmCtx);
{
// Get the pseudo file list for the parent directory
PseudoFileList searchList = fstate.getPseudoFileList(); if ( fstate != null)
{
// Get the pseudo file list for the parent directory
// Check if this is a single file or wildcard search PseudoFileList searchList = fstate.getPseudoFileList();
if ( WildCard.containsWildcards( searchPath)) // Check if this is a single file or wildcard search
{
// Create the search context, wildcard filter will take care of secondary filtering of the
// folder listing
WildCard wildCardFilter = new WildCard( paths[1], false); if ( WildCard.containsWildcards( searchPath))
return new PseudoFileListSearchContext( searchList, attrib, wildCardFilter); {
} // Create the search context, wildcard filter will take care of secondary filtering of the
else // folder listing
{
// Search the pseudo file list for the required file
PseudoFile pseudoFile = searchList.findFile( paths[1], false); WildCard wildCardFilter = new WildCard( paths[1], false);
if ( pseudoFile != null) return new PseudoFileListSearchContext( searchList, attrib, wildCardFilter);
{ }
// Create a search context using the single file details else
{
// Search the pseudo file list for the required file
PseudoFileList singleList = new PseudoFileList(); PseudoFile pseudoFile = searchList.findFile( paths[1], false);
singleList.addFile( pseudoFile); if ( pseudoFile != null)
{
// Create a search context using the single file details
return new PseudoFileListSearchContext( singleList, attrib, null); PseudoFileList singleList = new PseudoFileList();
} singleList.addFile( pseudoFile);
}
}
// File not found return new PseudoFileListSearchContext( singleList, attrib, null);
}
}
}
throw new FileNotFoundException( searchPath); // File not found
throw new FileNotFoundException( searchPath);
}
else if ( storePath.isLevel() == AVMPath.LevelId.HeadMetaData || storePath.isLevel() == AVMPath.LevelId.VersionMetaData)
{
// Return an empty file list for now
PseudoFileList metaFiles = new PseudoFileList();
return new PseudoFileListSearchContext( metaFiles, attrib, null);
}
} }
// Check if the path is a wildcard search // Check if the path is a wildcard search
sess.beginTransaction( m_transactionService, true); sess.beginReadTransaction( m_transactionService);
SearchContext context = null; SearchContext context = null;
if ( WildCard.containsWildcards( searchPath)) if ( WildCard.containsWildcards( searchPath))
{ {
// Get the file listing for the folder // Get the file listing for the folder
AVMNodeDescriptor[] fileList = m_avmService.getDirectoryListingArray( avmCtx.isVersion(), storePath.getAVMPath(), false); AVMNodeDescriptor[] fileList = m_avmService.getDirectoryListingArray( storePath.getVersion(), storePath.getAVMPath(), false);
// Create the search context // Create the search context
@@ -1447,7 +1473,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
// Get the single file/folder details // Get the single file/folder details
AVMNodeDescriptor nodeDesc = m_avmService.lookup( avmCtx.isVersion(), storePath.getAVMPath()); AVMNodeDescriptor nodeDesc = m_avmService.lookup( storePath.getVersion(), storePath.getAVMPath());
if ( nodeDesc != null) if ( nodeDesc != null)
{ {
@@ -1475,12 +1501,17 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
public void truncateFile(SrvSession sess, TreeConnection tree, NetworkFile file, long siz) public void truncateFile(SrvSession sess, TreeConnection tree, NetworkFile file, long siz)
throws java.io.IOException throws java.io.IOException
{ {
// Check if the file is a directory, or only has read access
if ( file.getGrantedAccess() == NetworkFile.READONLY)
throw new AccessDeniedException();
// If the content channel is not open for the file then start a transaction // If the content channel is not open for the file then start a transaction
AVMNetworkFile avmFile = (AVMNetworkFile) file; AVMNetworkFile avmFile = (AVMNetworkFile) file;
if ( avmFile.hasContentChannel() == false) if ( avmFile.hasContentChannel() == false || avmFile.isWritable() == false)
sess.beginTransaction( m_transactionService, true); sess.beginWriteTransaction( m_transactionService);
// Truncate or extend the file // Truncate or extend the file
@@ -1505,9 +1536,9 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
long fileoff) long fileoff)
throws java.io.IOException throws java.io.IOException
{ {
// Check if the file is a directory // Check if the file is a directory, or only has read access
if ( file.isDirectory()) if ( file.isDirectory() || file.getGrantedAccess() == NetworkFile.READONLY)
throw new AccessDeniedException(); throw new AccessDeniedException();
// If the content channel is not open for the file, or the channel is not writable, then start a transaction // If the content channel is not open for the file, or the channel is not writable, then start a transaction
@@ -1515,7 +1546,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
AVMNetworkFile avmFile = (AVMNetworkFile) file; AVMNetworkFile avmFile = (AVMNetworkFile) file;
if ( avmFile.hasContentChannel() == false || avmFile.isWritable() == false) if ( avmFile.hasContentChannel() == false || avmFile.isWritable() == false)
sess.beginTransaction( m_transactionService, true); sess.beginWriteTransaction( m_transactionService);
// Write the data to the file // Write the data to the file
@@ -1559,68 +1590,164 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
{ {
// Check if the path is to a store pseudo folder // Check if the path is to a store pseudo folder
if ( avmPath.isRootPath())
return null;
// Get the file state for the parent of the required folder
FileState fstate = null;
StringBuilder str = null;
PseudoFile psFile = null; PseudoFile psFile = null;
if ( avmPath.hasVersion() == false) switch ( avmPath.isLevel())
{ {
// Check for the path within the store layer // Store root folder
FileState fstate = avmCtx.getStateTable().findFileState( FileName.DOS_SEPERATOR_STR); case StoreRoot:
PseudoFileList pseudoList = fstate.getPseudoFileList();
psFile = pseudoList.findFile( avmPath.getStoreName(), false); // Get the root folder file state
}
else if ( avmPath.hasRelativePath() == false)
{
// Build the path to the parent store folder
StringBuilder storeStr = new StringBuilder(); fstate = avmCtx.getStateTable().findFileState( FileName.DOS_SEPERATOR_STR);
if ( fstate != null)
psFile = fstate.getPseudoFileList().findFile( avmPath.getStoreName(), false);
break;
storeStr.append( FileName.DOS_SEPERATOR); // Versions root or Head folder
storeStr.append( avmPath.getStoreName());
// Search for the file state for the store pseudo folder case VersionRoot:
case Head:
FileState storeState = avmCtx.getStateTable().findFileState( storeStr.toString()); // Create a path to the parent store
if ( storeState != null)
{
// Search the store pseudo folder file list for the required version
psFile = storeState.getPseudoFileList().findFile( avmPath.getVersionString(), false); str = new StringBuilder();
}
else
{
// Get the list of AVM store versions
try str.append( FileName.DOS_SEPERATOR);
{ str.append( avmPath.getStoreName());
// Get the list of versions for the store
List<VersionDescriptor> verList = m_avmService.getAVMStoreVersions( avmPath.getStoreName()); // Find/create the file state for the store
// Create a file state for the store path AVMPath storePath = new AVMPath( str.toString());
fstate = findPseudoState( storePath, avmCtx);
storeState = avmCtx.getStateTable().findFileState( storeStr.toString(), true, true); // Find the version root or head pseudo folder
// Add pseudo files for the versions to the store state if ( fstate != null)
{
if ( avmPath.isLevel() == AVMPath.LevelId.Head)
psFile = fstate.getPseudoFileList().findFile( AVMPath.VersionNameHead, true);
else
psFile = fstate.getPseudoFileList().findFile( AVMPath.VersionsFolder, true);
}
break;
for ( VersionDescriptor verDesc : verList) // Version folder
{
// Add the version pseudo folder
storeState.addPseudoFile( new VersionPseudoFile ( avmPath.getVersionString(), verDesc)); case Version:
}
// Search for the required version pseudo folder // Create a path to the versions folder
psFile = storeState.getPseudoFileList().findFile( avmPath.getVersionString(), false); str = new StringBuilder();
}
catch ( AVMNotFoundException ex) str.append( FileName.DOS_SEPERATOR);
{ str.append( avmPath.getStoreName());
// Invalid store name str.append( FileName.DOS_SEPERATOR);
} str.append( AVMPath.VersionsFolder);
}
} // Find/create the file state for the store
AVMPath verrootPath = new AVMPath( str.toString());
fstate = findPseudoState( verrootPath, avmCtx);
// Find the version pseudo file
if ( fstate != null)
{
// Build the version folder name string
str.setLength( 0);
str.append( AVMPath.VersionFolderPrefix);
str.append( avmPath.getVersion());
// find the version folder pseduo file
psFile = fstate.getPseudoFileList().findFile( str.toString(), true);
}
break;
// Head data or metadata folder
case HeadData:
case HeadMetaData:
// Create a path to the head folder
str = new StringBuilder();
str.append( FileName.DOS_SEPERATOR);
str.append( avmPath.getStoreName());
str.append( FileName.DOS_SEPERATOR);
str.append( AVMPath.VersionNameHead);
// Find/create the file state for the store
AVMPath headPath = new AVMPath( str.toString());
fstate = findPseudoState( headPath, avmCtx);
// Find the data or metadata pseudo folder
if ( fstate != null)
{
// Find the pseudo folder
if ( avmPath.isLevel() == AVMPath.LevelId.HeadData)
{
psFile = fstate.getPseudoFileList().findFile( AVMPath.DataFolder, true);
}
else
{
psFile = fstate.getPseudoFileList().findFile( AVMPath.MetaDataFolder, true);
}
}
break;
// Version data or metadata folder
case VersionData:
case VersionMetaData:
// Create a path to the version folder
str = new StringBuilder();
str.append( FileName.DOS_SEPERATOR);
str.append( avmPath.getStoreName());
str.append( FileName.DOS_SEPERATOR);
str.append( AVMPath.VersionFolderPrefix);
str.append( avmPath.getVersion());
// Find/create the file state for the store
AVMPath verPath = new AVMPath( str.toString());
fstate = findPseudoState( verPath, avmCtx);
// Find the data or metadata pseudo folder
if ( fstate != null)
{
// Find the pseudo folder
if ( avmPath.isLevel() == AVMPath.LevelId.VersionData)
{
psFile = fstate.getPseudoFileList().findFile( AVMPath.DataFolder, true);
}
else
{
psFile = fstate.getPseudoFileList().findFile( AVMPath.MetaDataFolder, true);
}
}
break;
}
// Return the pseudo file, or null if not found // Return the pseudo file, or null if not found
@@ -1636,72 +1763,148 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
*/ */
private final FileState findPseudoState( AVMPath avmPath, AVMContext avmCtx) private final FileState findPseudoState( AVMPath avmPath, AVMContext avmCtx)
{ {
// Make sure the is to a pseudo file/folder
if ( avmPath.isPseudoPath() == false)
return null;
// Check if the path is to a store pseudo folder // Check if the path is to a store pseudo folder
FileState fstate = null; FileState fstate = null;
StringBuilder str = null;
if ( avmPath.isRootPath()) switch ( avmPath.isLevel())
{ {
// Get the root path file state // Root of the hieararchy
fstate = avmCtx.getStateTable().findFileState( FileName.DOS_SEPERATOR_STR); case Root:
}
else if ( avmPath.hasVersion() == false)
{
// Build the path to the parent store folder
StringBuilder storeStr = new StringBuilder(); // Get the root path file state
storeStr.append( FileName.DOS_SEPERATOR); fstate = avmCtx.getStateTable().findFileState( FileName.DOS_SEPERATOR_STR);
storeStr.append( avmPath.getStoreName()); break;
// Search for the file state for the store pseudo folder // Store folder
fstate = avmCtx.getStateTable().findFileState( storeStr.toString()); case StoreRoot:
if ( fstate == null) // Build the path to the parent store folder
{
// Get the list of AVM store versions
try str = new StringBuilder();
str.append( FileName.DOS_SEPERATOR);
str.append( avmPath.getStoreName());
// Search for the file state for the store pseudo folder
fstate = avmCtx.getStateTable().findFileState( str.toString());
if ( fstate == null)
{ {
// Get the list of versions for the store
List<VersionDescriptor> verList = m_avmService.getAVMStoreVersions( avmPath.getStoreName());
// Create a file state for the store path // Create a file state for the store path
fstate = avmCtx.getStateTable().findFileState( storeStr.toString(), true, true); fstate = avmCtx.getStateTable().findFileState( str.toString(), true, true);
// Add a pseudo file for the head version // Add a pseudo file for the head version
fstate.addPseudoFile( new VersionPseudoFile( AVMPath.VersionNameHead)); fstate.addPseudoFile( new VersionPseudoFile( AVMPath.VersionNameHead));
// Add pseudo files for the versions to the store state // Add a pseudo file for the version root folder
if ( verList.size() > 0) fstate.addPseudoFile( new DummyFolderPseudoFile( AVMPath.VersionsFolder));
}
break;
// Head folder
case Head:
// Build the path to the store head version folder
str = new StringBuilder();
str.append( FileName.DOS_SEPERATOR);
str.append( avmPath.getStoreName());
str.append( FileName.DOS_SEPERATOR);
str.append( AVMPath.VersionNameHead);
// Search for the file state for the store head version pseudo folder
fstate = avmCtx.getStateTable().findFileState( str.toString());
if ( fstate == null)
{
// Create a file state for the store head folder path
fstate = avmCtx.getStateTable().findFileState( str.toString(), true, true);
// Add a pseudo file for the data pseudo folder
fstate.addPseudoFile( new DummyFolderPseudoFile( AVMPath.DataFolder));
// Add a pseudo file for the metadata pseudo folder
fstate.addPseudoFile( new DummyFolderPseudoFile( AVMPath.MetaDataFolder));
}
break;
// Version root folder
case VersionRoot:
// Get the list of AVM store versions
try
{
// Build the path to the parent store folder
str = new StringBuilder();
str.append( FileName.DOS_SEPERATOR);
str.append( avmPath.getStoreName());
str.append( FileName.DOS_SEPERATOR);
str.append( AVMPath.VersionsFolder);
// Create a file state for the store path
fstate = avmCtx.getStateTable().findFileState( str.toString(), true, true);
// Add pseudo folders if the list is empty
if ( fstate.hasPseudoFiles() == false)
{ {
StringBuilder verStr = new StringBuilder(); // Build the version folder name for the head version
for ( VersionDescriptor verDesc : verList) StringBuilder verStr = new StringBuilder( AVMPath.VersionFolderPrefix);
verStr.append( "-1");
// Add a pseudo file for the head version
fstate.addPseudoFile( new VersionPseudoFile( verStr.toString()));
// Get the list of versions for the store
List<VersionDescriptor> verList = m_avmService.getAVMStoreVersions( avmPath.getStoreName());
// Add pseudo files for the versions to the store state
if ( verList.size() > 0)
{ {
// Generate the version string for ( VersionDescriptor verDesc : verList)
String verName = null;
if ( verDesc.getVersionID() == -1)
verName = AVMPath.VersionNameHead;
else
{ {
verStr.setLength( 0); // Generate the version string
String verName = null;
verStr.setLength( AVMPath.VersionFolderPrefix.length());
verStr.append( verDesc.getVersionID()); verStr.append( verDesc.getVersionID());
verName = verStr.toString(); verName = verStr.toString();
// Add the version pseudo folder
fstate.addPseudoFile( new VersionPseudoFile ( verName, verDesc));
} }
// Add the version pseudo folder
fstate.addPseudoFile( new VersionPseudoFile ( verName, verDesc));
} }
} }
} }
@@ -1709,11 +1912,44 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface {
{ {
// Invalid store name // Invalid store name
} }
break;
} // Version folder
case Version:
// Build the path to the store version folder
str = new StringBuilder();
str.append( FileName.DOS_SEPERATOR);
str.append( avmPath.getStoreName());
str.append( FileName.DOS_SEPERATOR);
str.append( AVMPath.VersionFolderPrefix);
str.append( avmPath.getVersion());
// Search for the file state for the version pseudo folder
fstate = avmCtx.getStateTable().findFileState( str.toString());
if ( fstate == null)
{
// Create a file state for the version folder path
fstate = avmCtx.getStateTable().findFileState( str.toString(), true, true);
// Add a pseudo file for the data pseudo folder
fstate.addPseudoFile( new DummyFolderPseudoFile( AVMPath.DataFolder));
// Add a pseudo file for the metadata pseudo folder
fstate.addPseudoFile( new DummyFolderPseudoFile( AVMPath.MetaDataFolder));
}
break;
} }
// Return the file state // Return the file state
return fstate; return fstate;
} }

View File

@@ -36,13 +36,34 @@ public class AVMPath {
// Version id string for the head version // Version id string for the head version
public static final String VersionNameHead = "Head"; public static final String VersionNameHead = "HEAD";
// Folder name for the versions folder
public static final String VersionsFolder = "VERSION";
// Head and version sub-folders
public static final String DataFolder = "DATA";
public static final String MetaDataFolder = "METADATA";
// Version folder prefix
public static final String VersionFolderPrefix = "v";
// AVM path seperator // AVM path seperator
public static final char AVM_SEPERATOR = '/'; public static final char AVM_SEPERATOR = '/';
public static final String AVM_SEPERATOR_STR = "/"; public static final String AVM_SEPERATOR_STR = "/";
// Level identifiers
public enum LevelId { Invalid, Root, StoreRoot, Head, HeadData, HeadMetaData, VersionRoot, Version, VersionData, VersionMetaData, StorePath };
// Level identifier for this path
private LevelId m_levelId = LevelId.Invalid;
// Store name // Store name
private String m_storeName; private String m_storeName;
@@ -96,6 +117,16 @@ public class AVMPath {
parsePath( storeName, version, path); parsePath( storeName, version, path);
} }
/**
* Return the level id for the path
*
* @return LevelId
*/
public LevelId isLevel()
{
return m_levelId;
}
/** /**
* Return the store name * Return the store name
* *
@@ -175,7 +206,7 @@ public class AVMPath {
*/ */
public final boolean isValid() public final boolean isValid()
{ {
return m_storeName == null && m_path == null ? false : true; return m_levelId == LevelId.Invalid ? false : true;
} }
/** /**
@@ -185,7 +216,20 @@ public class AVMPath {
*/ */
public final boolean isPseudoPath() public final boolean isPseudoPath()
{ {
return m_version == InvalidVersionId || m_path == null ? true : false; return m_levelId == LevelId.Invalid || m_levelId == LevelId.StorePath ? false : true;
}
/**
* Check if hte path is a read-only part of the pseudo folder tree
*
* @return boolean
*/
public final boolean isReadOnlyPseudoPath()
{
if ( isLevel() == LevelId.Root || isLevel() == LevelId.StoreRoot || isLevel() == LevelId.VersionRoot ||
isLevel() == LevelId.Head || isLevel() == LevelId.Version)
return true;
return false;
} }
/** /**
@@ -195,9 +239,7 @@ public class AVMPath {
*/ */
public final boolean isRootPath() public final boolean isRootPath()
{ {
if ( m_path != null && m_path.equals( FileName.DOS_SEPERATOR_STR)) return m_levelId == LevelId.Root ? true : false;
return true;
return false;
} }
/** /**
@@ -221,85 +263,179 @@ public class AVMPath {
if ( paths == null || paths.length == 0) if ( paths == null || paths.length == 0)
{ {
m_path = FileName.DOS_SEPERATOR_STR; m_path = FileName.DOS_SEPERATOR_STR;
m_levelId = LevelId.Root;
return; return;
} }
// Set the store name // Set the store name
m_storeName = paths[0]; m_storeName = paths[0];
m_levelId = LevelId.StoreRoot;
if ( paths.length > 1) if ( paths.length > 1)
{ {
// Validate the version id // Validate the next element, should be either the HEAD or VERSIONS folder
String verStr = paths[1]; String levelStr = paths[1];
if ( verStr.equalsIgnoreCase( VersionNameHead))
if ( levelStr.equalsIgnoreCase( VersionNameHead))
{
m_version = -1; m_version = -1;
m_levelId = LevelId.Head;
}
else if ( levelStr.equalsIgnoreCase( VersionsFolder))
{
m_levelId = LevelId.VersionRoot;
}
else else
{ {
try // Invalid folder at the current level
{
// Parse the version id
m_version = Integer.parseInt( verStr); m_levelId = LevelId.Invalid;
return;
// Validate the version id
if ( m_version < 0)
{
// Invalid version id
m_storeName = null;
return;
}
}
catch ( NumberFormatException ex)
{
m_storeName = null;
return;
}
} }
// If there additional path elements build the share and AVM relative paths // Check the next level, if available
if ( paths.length > 2) if ( paths.length > 2)
{ {
// Build the share relative path // If the previous level is the versions root then the next level should be a
// version id folder
StringBuilder pathStr = new StringBuilder(); String folderName = paths[2];
int pathIdx = 3;
for ( int i = 2; i < paths.length; i++) if ( isLevel() == LevelId.VersionRoot)
{ {
pathStr.append( FileName.DOS_SEPERATOR); // Check that the folder name starts with the version folder prefix
pathStr.append( paths[i]);
if ( folderName != null && folderName.startsWith( VersionFolderPrefix) &&
folderName.length() > VersionFolderPrefix.length())
{
try
{
// Parse the version id
m_version = Integer.parseInt( folderName.substring( VersionFolderPrefix.length()));
m_levelId = LevelId.Version;
// Validate the version id
if ( m_version < -1)
{
// Invalid version id
m_levelId = LevelId.Invalid;
return;
}
}
catch ( NumberFormatException ex)
{
m_levelId = LevelId.Invalid;
return;
}
// Check for the next level
if ( paths.length > 3)
{
// Get the next level name
folderName = paths[3];
pathIdx++;
// Check for the data folder
if ( folderName.equalsIgnoreCase( DataFolder))
{
m_levelId = LevelId.VersionData;
// Set the path to the root of the store
m_path = FileName.DOS_SEPERATOR_STR;
}
else if ( folderName.equalsIgnoreCase( MetaDataFolder))
{
m_levelId = LevelId.VersionMetaData;
// Set the path to the root of the metadata
m_path = FileName.DOS_SEPERATOR_STR;
}
else
{
m_levelId = LevelId.Invalid;
return;
}
}
}
else
{
m_levelId = LevelId.Invalid;
return;
}
} }
m_path = pathStr.toString(); // If the previous level is head the next level should be the data or metadata folder
else if ( isLevel() == LevelId.Head)
{
// Check for the data folder
if ( folderName.equalsIgnoreCase( DataFolder))
{
m_levelId = LevelId.HeadData;
// Set the path to the root of the store
m_path = FileName.DOS_SEPERATOR_STR;
}
else if ( folderName.equalsIgnoreCase( MetaDataFolder))
{
m_levelId = LevelId.HeadMetaData;
// Set the path to the root of the metadata
m_path = FileName.DOS_SEPERATOR_STR;
}
else
{
m_levelId = LevelId.Invalid;
return;
}
}
// If there are remaining paths then build a relative path
if ( paths.length > pathIdx)
{
StringBuilder pathStr = new StringBuilder();
for ( int i = pathIdx; i < paths.length; i++)
{
pathStr.append( FileName.DOS_SEPERATOR);
pathStr.append( paths[i]);
}
m_path = pathStr.toString();
// Set the level to indicate a store relative path
m_levelId = LevelId.StorePath;
}
// Build the AVM path, in <store>:/<path> format // Build the AVM path, in <store>:/<path> format
pathStr.setLength( 0); if ( m_path != null)
{
StringBuilder pathStr = new StringBuilder();
pathStr.append( m_storeName); pathStr.append( m_storeName);
pathStr.append( ":"); pathStr.append( ":");
pathStr.append( m_path.replace( FileName.DOS_SEPERATOR, AVM_SEPERATOR)); pathStr.append( m_path.replace( FileName.DOS_SEPERATOR, AVM_SEPERATOR));
m_avmPath = pathStr.toString(); m_avmPath = pathStr.toString();
} }
else
{
// Share relative path is the root of the share
m_path = FileName.DOS_SEPERATOR_STR;
// Build the AVM path
StringBuilder pathStr = new StringBuilder();
pathStr.append( m_storeName);
pathStr.append( ":/");
m_avmPath = pathStr.toString();
} }
} }
} }
@@ -315,6 +451,8 @@ public class AVMPath {
{ {
// Clear current settings // Clear current settings
m_levelId = LevelId.Invalid;
m_storeName = null; m_storeName = null;
m_version = InvalidVersionId; m_version = InvalidVersionId;
m_path = null; m_path = null;
@@ -354,6 +492,10 @@ public class AVMPath {
} }
m_avmPath = avmPath.toString(); m_avmPath = avmPath.toString();
// Indicate that the path is to a store relative path
m_levelId = LevelId.StorePath;
} }
/** /**
@@ -365,19 +507,76 @@ public class AVMPath {
{ {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
str.append("["); switch ( m_levelId)
str.append(getStoreName()); {
str.append(","); case Invalid:
str.append("[Invalid");
if ( hasVersion()) break;
str.append(getVersion()); case Root:
else str.append("[Root");
str.append("NoVersion"); break;
case StoreRoot:
str.append(","); str.append("[StoresRoot");
str.append(getRelativePath()); break;
str.append(":"); case Head:
str.append(getAVMPath()); str.append("[");
str.append(getStoreName());
str.append(":HEAD");
break;
case HeadData:
str.append("[");
str.append(getStoreName());
str.append(":HEAD\\");
str.append( DataFolder);
break;
case HeadMetaData:
str.append("[");
str.append(getStoreName());
str.append(":HEAD\\");
str.append( MetaDataFolder);
break;
case VersionRoot:
str.append("[");
str.append(getStoreName());
str.append(":Versions");
break;
case Version:
str.append("[");
str.append(getStoreName());
str.append(":");
str.append(VersionFolderPrefix);
str.append(getVersion());
break;
case VersionData:
str.append("[");
str.append(getStoreName());
str.append(":");
str.append(VersionFolderPrefix);
str.append(getVersion());
str.append("\\");
str.append( DataFolder);
break;
case VersionMetaData:
str.append("[");
str.append(getStoreName());
str.append(":");
str.append(VersionFolderPrefix);
str.append(getVersion());
str.append("\\");
str.append( MetaDataFolder);
break;
case StorePath:
str.append("[");
str.append(getStoreName());
str.append(":");
str.append(VersionFolderPrefix);
str.append(getVersion());
str.append(",");
str.append(getRelativePath());
str.append(":");
str.append(getAVMPath());
break;
}
str.append("]"); str.append("]");
return str.toString(); return str.toString();

View File

@@ -237,7 +237,7 @@ public class AVMShareMapper implements ShareMapper {
AVMDiskDriver avmDrv = (AVMDiskDriver) m_config.getAvmDiskInterface(); AVMDiskDriver avmDrv = (AVMDiskDriver) m_config.getAvmDiskInterface();
AVMService avmService = avmDrv.getAvmService(); AVMService avmService = avmDrv.getAvmService();
sess.beginTransaction( avmDrv.getTransactionService(), true); sess.beginReadTransaction( avmDrv.getTransactionService());
try try
{ {

View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2005-2006 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.filesys.avm;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFolderNetworkFile;
/**
* Dummy Folder Pseudo File Class
*
* <p>Represents a dummy folder within the virtualization filesystem view.
*
* @author gkspencer
*/
public class DummyFolderPseudoFile extends PseudoFile {
/**
* Class constructor
*
* @param fname String
*/
public DummyFolderPseudoFile( String fname)
{
super( fname, FileAttribute.Directory + FileAttribute.ReadOnly);
// Create static file information from the folder details
FileInfo fInfo = new FileInfo( fname, 0L, FileAttribute.Directory + FileAttribute.ReadOnly);
fInfo.setCreationDateTime( System.currentTimeMillis());
setFileInfo( fInfo);
}
/**
* Return a network file for reading/writing the pseudo file
*
* @param netPath String
* @return NetworkFile
*/
@Override
public NetworkFile getFile(String netPath) {
// Split the path to get the name
String[] paths = FileName.splitPath( netPath);
// Create a network file for the folder
return new PseudoFolderNetworkFile( paths[1], netPath);
}
/**
* Return the file information for the pseudo file
*
* @return FileInfo
*/
@Override
public FileInfo getFileInfo() {
return getInfo();
}
}

View File

@@ -468,6 +468,32 @@ public abstract class SrvSession
} }
} }
/**
* Create a read transaction, if not already active
*
* @param transService TransactionService
* @return boolean
* @exception AlfrescoRuntimeException
*/
public final boolean beginReadTransaction( TransactionService transService)
throws AlfrescoRuntimeException
{
return beginTransaction(transService, true);
}
/**
* Create a write transaction, if not already active
*
* @param transService TransactionService
* @return boolean
* @exception AlfrescoRuntimeException
*/
public final boolean beginWriteTransaction( TransactionService transService)
throws AlfrescoRuntimeException
{
return beginTransaction(transService, false);
}
/** /**
* Create and start a transaction, if not already active * Create and start a transaction, if not already active
* *
@@ -476,7 +502,7 @@ public abstract class SrvSession
* @return boolean * @return boolean
* @exception AlfrescoRuntimeException * @exception AlfrescoRuntimeException
*/ */
public final boolean beginTransaction(TransactionService transService, boolean readOnly) private final boolean beginTransaction(TransactionService transService, boolean readOnly)
throws AlfrescoRuntimeException throws AlfrescoRuntimeException
{ {
boolean created = false; boolean created = false;

View File

@@ -79,6 +79,19 @@ public class ClientInfo
private NodeRef m_homeNode; private NodeRef m_homeNode;
// Group and user id
private int m_gid = -1;
private int m_uid = -1;
// List of groups for this user
private int[] m_groups;
// NFS authentication type
private int m_nfsAuthType = -1;
/** /**
* Default constructor * Default constructor
*/ */
@@ -331,6 +344,56 @@ public class ClientInfo
return m_homeNode; return m_homeNode;
} }
/**
* Get the group id
*
* @return int
*/
public final int getGid()
{
return m_gid;
}
/**
* Return the user id
*
* @return int
*/
public final int getUid()
{
return m_uid;
}
/**
* Determine if the client has additional groups
*
* @return boolean
*/
public final boolean hasGroupsList()
{
return m_groups != null ? true : false;
}
/**
* Return the additional groups list
*
* @return int[]
*/
public final int[] getGroupsList()
{
return m_groups;
}
/**
* Return the NFS authentication type
*
* @return int
*/
public final int getNFSAuthenticationType()
{
return m_nfsAuthType;
}
/** /**
* Set the remote users domain * Set the remote users domain
* *
@@ -454,6 +517,46 @@ public class ClientInfo
m_homeNode = homeNode; m_homeNode = homeNode;
} }
/**
* Set the group id
*
* @param gid int
*/
public final void setGid(int gid)
{
m_gid = gid;
}
/**
* Set the user id
*
* @param uid int
*/
public final void setUid(int uid)
{
m_uid = uid;
}
/**
* Set the groups list
*
* @param groups int[]
*/
public final void setGroupsList(int[] groups)
{
m_groups = groups;
}
/**
* Set the NFS authentication type
*
* @param type int
*/
public final void setNFSAuthenticationType(int type)
{
m_nfsAuthType = type;
}
/** /**
* Display the client information as a string * Display the client information as a string
* *

View File

@@ -72,6 +72,8 @@ import org.alfresco.filesys.server.core.SharedDeviceList;
import org.alfresco.filesys.server.filesys.DefaultShareMapper; import org.alfresco.filesys.server.filesys.DefaultShareMapper;
import org.alfresco.filesys.server.filesys.DiskInterface; import org.alfresco.filesys.server.filesys.DiskInterface;
import org.alfresco.filesys.server.filesys.DiskSharedDevice; import org.alfresco.filesys.server.filesys.DiskSharedDevice;
//import org.alfresco.filesys.server.oncrpc.DefaultRpcAuthenticator;
//import org.alfresco.filesys.server.oncrpc.RpcAuthenticator;
import org.alfresco.filesys.smb.ServerType; import org.alfresco.filesys.smb.ServerType;
import org.alfresco.filesys.smb.TcpipSMB; import org.alfresco.filesys.smb.TcpipSMB;
import org.alfresco.filesys.smb.server.repo.ContentContext; import org.alfresco.filesys.smb.server.repo.ContentContext;
@@ -107,6 +109,7 @@ public class ServerConfiguration extends AbstractLifecycleBean
private static final String ConfigArea = "file-servers"; private static final String ConfigArea = "file-servers";
private static final String ConfigCIFS = "CIFS Server"; private static final String ConfigCIFS = "CIFS Server";
private static final String ConfigFTP = "FTP Server"; private static final String ConfigFTP = "FTP Server";
private static final String ConfigNFS = "NFS Server";
private static final String ConfigFilesystems = "Filesystems"; private static final String ConfigFilesystems = "Filesystems";
private static final String ConfigSecurity = "Filesystem Security"; private static final String ConfigSecurity = "Filesystem Security";
@@ -135,6 +138,11 @@ public class ServerConfiguration extends AbstractLifecycleBean
private static final String DefaultFTPAnonymousAccount = "anonymous"; private static final String DefaultFTPAnonymousAccount = "anonymous";
// NFS server debug type strings
private static final String m_nfsDebugStr[] = { "RXDATA", "TXDATA", "DUMPDATA", "SEARCH", "INFO", "FILE",
"FILEIO", "ERROR", "TIMING", "DIRECTORY", "SESSION" };
// Platform types // Platform types
public enum PlatformType public enum PlatformType
@@ -170,6 +178,7 @@ public class ServerConfiguration extends AbstractLifecycleBean
private boolean m_smbEnable = true; private boolean m_smbEnable = true;
private boolean m_ftpEnable = true; private boolean m_ftpEnable = true;
private boolean m_nfsEnable = true;
// Server name // Server name
@@ -242,8 +251,8 @@ public class ServerConfiguration extends AbstractLifecycleBean
// Flags to indicate if NetBIOS, native TCP/IP SMB and/or Win32 NetBIOS // Flags to indicate if NetBIOS, native TCP/IP SMB and/or Win32 NetBIOS
// should be enabled // should be enabled
private boolean m_netBIOSEnable = true; private boolean m_netBIOSEnable = false;
private boolean m_tcpSMBEnable = false; private boolean m_tcpSMBEnable = false;
private boolean m_win32NBEnable = false; private boolean m_win32NBEnable = false;
// Address to bind the SMB server to, if null all local addresses are used // Address to bind the SMB server to, if null all local addresses are used
@@ -306,6 +315,43 @@ public class ServerConfiguration extends AbstractLifecycleBean
private int m_ftpDebug; private int m_ftpDebug;
//--------------------------------------------------------------------------------
// NFS specific configuration parameters
//
// Enable the port mapper server
private boolean m_nfsPortMapper;
// Port mapper port
private int m_portMapperPort;
// Mount server port
private int m_mountServerPort;
// NFS server port
private int m_nfsServerPort;
// NFS debug flags
private int m_nfsDebug;
// Port mapper and mount server debug enable
private boolean m_portMapDebug;
private boolean m_mountServerDebug;
// Thread pool size and packet pool size
private int m_nfsThreadPoolSize;
private int m_nfsPacketPoolSize;
// RPC authenticator implementation
// private RpcAuthenticator m_rpcAuthenticator;
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
// Global server configuration // Global server configuration
// //
@@ -624,6 +670,26 @@ public class ServerConfiguration extends AbstractLifecycleBean
logger.error("FTP server configuration error, " + ex.getMessage(), ex); logger.error("FTP server configuration error, " + ex.getMessage(), ex);
} }
// Initialize the NFS server
try
{
// Process the NFS server configuration
config = configService.getConfig(ConfigNFS, configCtx);
processNFSServerConfig(config);
// Log the successful startup
logger.info("NFS server started");
}
catch (Exception ex)
{
// Configuration error
logger.error("FTP server configuration error, " + ex.getMessage(), ex);
}
} }
else else
{ {
@@ -1596,6 +1662,174 @@ public class ServerConfiguration extends AbstractLifecycleBean
} }
} }
/**
* Process the NFS server configuration
*
* @param config Config
*/
private final void processNFSServerConfig(Config config)
{
/**
// If the configuration section is not valid then NFS is disabled
if ( config == null)
{
setNFSServerEnabled(false);
return;
}
// Check if the port mapper is enabled
if ( config.getConfigElement("enablePortMapper") != null)
m_nfsPortMapper = true;
// Check for the thread pool size
ConfigElement elem = config.getConfigElement("ThreadPool");
if ( elem != null) {
try {
// Convert the pool size value
int poolSize = Integer.parseInt(elem.getValue());
// Range check the pool size value
if ( poolSize < 4)
throw new AlfrescoRuntimeException("NFS thread pool size is below minimum of 4");
// Set the thread pool size
m_nfsThreadPoolSize = poolSize;
}
catch (NumberFormatException ex) {
throw new AlfrescoRuntimeException("Invalid NFS thread pool size setting, " + elem.getValue());
}
}
// NFS packet pool size
elem = config.getConfigElement("PacketPool");
if ( elem != null) {
try {
// Convert the packet pool size value
int pktPoolSize = Integer.parseInt(elem.getValue());
// Range check the pool size value
if ( pktPoolSize < 10)
throw new AlfrescoRuntimeException("NFS packet pool size is below minimum of 10");
if ( pktPoolSize < getNFSThreadPoolSize() + 1)
throw new AlfrescoRuntimeException("NFS packet pool must be at least thread pool size plus one");
// Set the packet pool size
m_nfsPacketPoolSize = pktPoolSize;
}
catch (NumberFormatException ex) {
throw new AlfrescoRuntimeException("Invalid NFS packet pool size setting, " + elem.getValue());
}
}
// Check for a port mapper server port
elem = config.getConfigElement("PortMapperPort");
if ( elem != null) {
try {
m_portMapperPort = Integer.parseInt(elem.getValue());
if ( getPortMapperPort() <= 0 || getPortMapperPort() >= 65535)
throw new AlfrescoRuntimeException("Port mapper server port out of valid range");
}
catch (NumberFormatException ex) {
throw new AlfrescoRuntimeException("Invalid port mapper server port");
}
}
// Check for a mount server port
elem = config.getConfigElement("MountServerPort");
if ( elem != null) {
try {
m_mountServerPort = Integer.parseInt(elem.getValue());
if ( getMountServerPort() <= 0 || getMountServerPort() >= 65535)
throw new AlfrescoRuntimeException("Mount server port out of valid range");
}
catch (NumberFormatException ex) {
throw new AlfrescoRuntimeException("Invalid mount server port");
}
}
// Check for an NFS server port
elem = config.getConfigElement("NFSServerPort");
if ( elem != null) {
try {
m_nfsServerPort = Integer.parseInt(elem.getValue());
if ( getNFSServerPort() <= 0 || getNFSServerPort() >= 65535)
throw new AlfrescoRuntimeException("NFS server port out of valid range");
}
catch (NumberFormatException ex) {
throw new AlfrescoRuntimeException("Invalid NFS server port");
}
}
// Check if NFS debug is enabled
elem = config.getConfigElement("debug");
if (elem != null) {
// Check for NFS debug flags
String flags = elem.getAttribute("flags");
int nfsDbg = 0;
if ( flags != null) {
// Parse the flags
flags = flags.toUpperCase();
StringTokenizer token = new StringTokenizer(flags,",");
while ( token.hasMoreTokens()) {
// Get the current debug flag token
String dbg = token.nextToken().trim();
// Find the debug flag name
int idx = 0;
while ( idx < m_nfsDebugStr.length && m_nfsDebugStr[idx].equalsIgnoreCase(dbg) == false)
idx++;
if ( idx >= m_nfsDebugStr.length)
throw new AlfrescoRuntimeException("Invalid NFS debug flag, " + dbg);
// Set the debug flag
nfsDbg += 1 << idx;
}
}
// Set the NFS debug flags
m_nfsDebug = nfsDbg;
}
// Create the RPC authenticator
m_rpcAuthenticator = new DefaultRpcAuthenticator();
**/
}
/** /**
* Process the filesystems configuration * Process the filesystems configuration
* *
@@ -2931,6 +3165,16 @@ public class ServerConfiguration extends AbstractLifecycleBean
m_ftpEnable = ena; m_ftpEnable = ena;
} }
/**
* Set the NFS server enabled state
*
* @param ena boolean
*/
public final void setNFSServerEnabled(boolean ena)
{
m_nfsEnable = ena;
}
/** /**
* Set the authenticator to be used to authenticate users and share connections for CIFS. * Set the authenticator to be used to authenticate users and share connections for CIFS.
* *
@@ -3445,6 +3689,118 @@ public class ServerConfiguration extends AbstractLifecycleBean
m_ftpDebug = dbg; m_ftpDebug = dbg;
} }
/**
* Check if the NFS server is enabled
*
* @return boolean
*/
public final boolean isNFSServerEnabled()
{
return m_nfsEnable;
}
/**
* Determine if port mapper debug is enabled
*
* @return boolean
*/
public final boolean hasPortMapperDebug()
{
return m_portMapDebug;
}
/**
* Determine if mount server debug is enabled
*
* @return boolean
*/
public final boolean hasMountServerDebug()
{
return m_mountServerDebug;
}
/**
* Check if the NFS port mapper is enabled
*
* @return boolean
*/
public final boolean hasNFSPortMapper()
{
return m_nfsPortMapper;
}
/**
* Return the port for port mapper to use, or zero for the default port
*
* @return int
*/
public final int getPortMapperPort()
{
return m_portMapperPort;
}
/**
* Return the port the mount server should use, or zero for the default port
*
* @return int
*/
public final int getMountServerPort()
{
return m_mountServerPort;
}
/**
* Return the port the NFS server should use, or zero for the default port
*
* @return int
*/
public final int getNFSServerPort()
{
return m_nfsServerPort;
}
/**
* Return the NFS debug flags
*
* @return int
*/
public final int getNFSDebug()
{
return m_nfsDebug;
}
/**
* Return the NFS thread pool size
*
* @return int
*/
public final int getNFSThreadPoolSize()
{
return m_nfsThreadPoolSize;
}
/**
* Return the NFS server packet pool size, or -1 for the default size
*
* @return int
*/
public final int getNFSPacketPoolSize()
{
return m_nfsPacketPoolSize;
}
/**
* Get the authenticator object that is used to provide RPC authentication (for the portmapper, mount server and
* NFS server)
*
* @return RpcAuthenticator
*/
/**
public final RpcAuthenticator getRpcAuthenticator()
{
return m_rpcAuthenticator;
}
**/
/** /**
* Close the server configuration, used to close various components that are shared between protocol * Close the server configuration, used to close various components that are shared between protocol
* handlers. * handlers.

View File

@@ -38,17 +38,17 @@ public class FileInfo implements Serializable
// //
// Set file information flags // Set file information flags
public static final int SetFileSize = 0x0001; public static final int SetFileSize = 0x0001;
public static final int SetAllocationSize = 0x0002; public static final int SetAllocationSize = 0x0002;
public static final int SetAttributes = 0x0004; public static final int SetAttributes = 0x0004;
public static final int SetModifyDate = 0x0008; public static final int SetModifyDate = 0x0008;
public static final int SetCreationDate = 0x0010; public static final int SetCreationDate = 0x0010;
public static final int SetAccessDate = 0x0020; public static final int SetAccessDate = 0x0020;
public static final int SetChangeDate = 0x0040; public static final int SetChangeDate = 0x0040;
public static final int SetGid = 0x0080; public static final int SetGid = 0x0080;
public static final int SetUid = 0x0100; public static final int SetUid = 0x0100;
public static final int SetMode = 0x0200; public static final int SetMode = 0x0200;
public static final int SetDeleteOnClose = 0x0400; public static final int SetDeleteOnClose = 0x0400;
// File name string // File name string
@@ -108,10 +108,13 @@ public class FileInfo implements Serializable
private boolean m_deleteOnClose; private boolean m_deleteOnClose;
// File type
private int m_fileType;
// Set file information flags // Set file information flags
// //
// Used to indicate which values in the file information object are valid and should be used to // Used to indicate which values in the file information object are valid and should be used to set
// set
// the file information. // the file information.
private int m_setFlags; private int m_setFlags;
@@ -527,6 +530,16 @@ public class FileInfo implements Serializable
return (m_attr & FileAttribute.Archive) != 0 ? true : false; return (m_attr & FileAttribute.Archive) != 0 ? true : false;
} }
/**
* Return the file type
*
* @return int
*/
public final int isFileType()
{
return m_fileType;
}
/** /**
* Determine if the group id field has been set * Determine if the group id field has been set
* *
@@ -833,6 +846,16 @@ public class FileInfo implements Serializable
m_mode = mode; m_mode = mode;
} }
/**
* Set the file type
*
* @param typ int
*/
public final void setFileType(int typ)
{
m_fileType = typ;
}
/** /**
* Set the set file information flags to indicated which values are to be set * Set the set file information flags to indicated which values are to be set
* *

View File

@@ -101,6 +101,11 @@ public class FileOpenParams
private int m_mode = -1; private int m_mode = -1;
// File type and symbolic name
private int m_fileType;
private String m_symName;
/** /**
* Class constructor for Core SMB dialect Open SMB requests * Class constructor for Core SMB dialect Open SMB requests
* *
@@ -454,6 +459,36 @@ public class FileOpenParams
return false; return false;
} }
/**
* Return the file type
*
* @return int
*/
public final int isFileType()
{
return m_fileType;
}
/**
* determine if the target of the create/open is a symbolic link
*
* @return boolean
*/
public final boolean isSymbolicLink()
{
return isFileType() == FileType.SymbolicLink;
}
/**
* Return the symbolic link name
*
* @return String
*/
public final String getSymbolicLinkName()
{
return m_symName;
}
/** /**
* Return the shared access mode, zero equals allow any shared access * Return the shared access mode, zero equals allow any shared access
* *
@@ -584,6 +619,27 @@ public class FileOpenParams
m_createOptions = m_createOptions | flag; m_createOptions = m_createOptions | flag;
} }
/**
* Set the file type
*
* @param typ int
*/
public final void setFileType(int typ)
{
m_fileType = typ;
}
/**
* Set the symbolic link name
*
* @param name String
*/
public final void setSymbolicLink(String name)
{
m_symName = name;
m_fileType = FileType.SymbolicLink;
}
/** /**
* Convert a Core/LanMan access mode to an NT access mode * Convert a Core/LanMan access mode to an NT access mode
* *

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.filesys.server.filesys;
/*
* FileType.java
*
* Copyright (c) Starlasoft 2006. All rights reserved.
*/
/**
* File Type Class
*
* <p>File type constants.
*
* @author GKSpencer
*/
public class FileType {
// File types
public static final int RegularFile = 1;
public static final int Directory = 2;
public static final int SymbolicLink = 3;
public static final int HardLink = 4;
public static final int Device = 5;
/**
* Return a file type as a string
*
* @param typ int
* @return String
*/
public final static String asString(int typ) {
String typStr = "Unknown";
switch (typ) {
case RegularFile:
typStr = "File";
break;
case Directory:
typStr = "Directory";
break;
case SymbolicLink:
typStr = "SymbolicLink";
break;
case HardLink:
typStr = "HardLink";
break;
case Device:
typStr = "Device";
break;
}
return typStr;
}
}

View File

@@ -571,7 +571,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Get the file information for the node // Get the file information for the node
session.beginTransaction(transactionService, true); session.beginReadTransaction(transactionService);
finfo = cifsHelper.getFileInformation(nodeRef); finfo = cifsHelper.getFileInformation(nodeRef);
// DEBUG // DEBUG
@@ -587,7 +587,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Start a transaction // Start a transaction
session.beginTransaction(transactionService, true); session.beginReadTransaction(transactionService);
String[] paths = FileName.splitPath( path); String[] paths = FileName.splitPath( path);
@@ -684,7 +684,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, true); sess.beginReadTransaction(transactionService);
// If the state table is available see if we can speed up the search using either cached // 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 // file information or find the folder node to be searched without having to walk the path
@@ -887,7 +887,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Get the node for the folder path // Get the node for the folder path
sess.beginTransaction(transactionService, true); sess.beginReadTransaction(transactionService);
fstate.setNodeRef( getNodeForPath( tree, paths[0])); fstate.setNodeRef( getNodeForPath( tree, paths[0]));
// Add pseudo files to the folder // Add pseudo files to the folder
@@ -908,7 +908,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, true); sess.beginReadTransaction(transactionService);
// Get the node for the folder path // Get the node for the folder path
@@ -950,7 +950,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, true); sess.beginReadTransaction(transactionService);
// Get the file information to check if the file/folder exists // Get the file information to check if the file/folder exists
@@ -1006,7 +1006,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, false); sess.beginWriteTransaction(transactionService);
try try
{ {
@@ -1213,7 +1213,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, false); sess.beginWriteTransaction(transactionService);
try try
{ {
@@ -1327,7 +1327,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, false); sess.beginWriteTransaction(transactionService);
try try
{ {
@@ -1434,7 +1434,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, false); sess.beginWriteTransaction(transactionService);
// get the device root // get the device root
@@ -1522,7 +1522,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, false); sess.beginWriteTransaction(transactionService);
// Get the associated file state // Get the associated file state
@@ -1614,7 +1614,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, false); sess.beginWriteTransaction(transactionService);
// Get the device context // Get the device context
@@ -1690,7 +1690,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
public void renameFile(SrvSession sess, TreeConnection tree, String oldName, String newName) throws IOException public void renameFile(SrvSession sess, TreeConnection tree, String oldName, String newName) throws IOException
{ {
// Create the transaction // Create the transaction
sess.beginTransaction(transactionService, false);
sess.beginWriteTransaction(transactionService);
try try
{ {

View File

@@ -285,7 +285,7 @@ public class ContentIOControlHandler implements IOControlHandler
{ {
// Start a transaction // Start a transaction
sess.beginTransaction( getTransactionService(), true); sess.beginReadTransaction( getTransactionService());
// Get the file name from the request // Get the file name from the request
@@ -531,7 +531,7 @@ public class ContentIOControlHandler implements IOControlHandler
// Start a transaction // Start a transaction
sess.beginTransaction( getTransactionService(), true); sess.beginReadTransaction( getTransactionService());
// Get an authentication ticket for the client, or validate the existing ticket. The ticket can be used when // Get an authentication ticket for the client, or validate the existing ticket. The ticket can be used when
// generating URLs for the client-side application so that the user does not have to re-authenticate // generating URLs for the client-side application so that the user does not have to re-authenticate

View File

@@ -84,7 +84,7 @@ public class CheckInOutDesktopAction extends DesktopAction {
// Start a transaction // Start a transaction
params.getSession().beginTransaction( transService, false); params.getSession().beginWriteTransaction( transService);
// Process the list of target nodes // Process the list of target nodes

View File

@@ -274,7 +274,7 @@ public class JavaScriptDesktopAction extends DesktopAction {
// Start a transaction // Start a transaction
TransactionService transService = getServiceRegistry().getTransactionService(); TransactionService transService = getServiceRegistry().getTransactionService();
params.getSession().beginTransaction( transService, false); params.getSession().beginWriteTransaction( transService);
// Access the script service // Access the script service
@@ -293,7 +293,7 @@ public class JavaScriptDesktopAction extends DesktopAction {
// Start a transaction // Start a transaction
params.getSession().beginTransaction( transService, false); params.getSession().beginWriteTransaction( transService);
// Run the script // Run the script