mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Checkpoint of file state refactoring.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4417 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -20,6 +20,8 @@ package org.alfresco.filesys.avm;
|
|||||||
import org.alfresco.filesys.server.filesys.DiskDeviceContext;
|
import org.alfresco.filesys.server.filesys.DiskDeviceContext;
|
||||||
import org.alfresco.filesys.server.filesys.FileSystem;
|
import org.alfresco.filesys.server.filesys.FileSystem;
|
||||||
import org.alfresco.filesys.server.filesys.SrvDiskInfo;
|
import org.alfresco.filesys.server.filesys.SrvDiskInfo;
|
||||||
|
import org.alfresco.filesys.server.state.FileStateReaper;
|
||||||
|
import org.alfresco.filesys.server.state.FileStateTable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AVM Filesystem Context Class
|
* AVM Filesystem Context Class
|
||||||
@@ -41,15 +43,21 @@ public class AVMContext extends DiskDeviceContext {
|
|||||||
private String m_storePath;
|
private String m_storePath;
|
||||||
private int m_version = VERSION_HEAD;
|
private int m_version = VERSION_HEAD;
|
||||||
|
|
||||||
|
// File state table and associated file state reaper
|
||||||
|
|
||||||
|
private FileStateTable m_stateTable;
|
||||||
|
private FileStateReaper m_stateReaper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class constructor
|
* Class constructor
|
||||||
*
|
*
|
||||||
|
* @param filesysName String
|
||||||
* @param storePath String
|
* @param storePath String
|
||||||
* @param version int
|
* @param version int
|
||||||
*/
|
*/
|
||||||
public AVMContext( String storePath, int version)
|
public AVMContext( String filesysName, String storePath, int version)
|
||||||
{
|
{
|
||||||
super( storePath + "(" + version + ")");
|
super( filesysName, storePath + "(" + version + ")");
|
||||||
|
|
||||||
// Set the store root path, remove any trailing slash as relative paths will be appended to this value
|
// Set the store root path, remove any trailing slash as relative paths will be appended to this value
|
||||||
|
|
||||||
@@ -106,8 +114,64 @@ public class AVMContext extends DiskDeviceContext {
|
|||||||
*/
|
*/
|
||||||
public void CloseContext() {
|
public void CloseContext() {
|
||||||
|
|
||||||
|
// Deregister the file state table from the reaper
|
||||||
|
|
||||||
|
if ( m_stateTable != null)
|
||||||
|
enableStateTable( false, m_stateReaper);
|
||||||
|
|
||||||
// Call the base class
|
// Call the base class
|
||||||
|
|
||||||
super.CloseContext();
|
super.CloseContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the file state table is enabled
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public final boolean hasStateTable()
|
||||||
|
{
|
||||||
|
return m_stateTable != null ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the file state table
|
||||||
|
*
|
||||||
|
* @return FileStateTable
|
||||||
|
*/
|
||||||
|
public final FileStateTable getStateTable()
|
||||||
|
{
|
||||||
|
return m_stateTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable the file state table
|
||||||
|
*
|
||||||
|
* @param ena boolean
|
||||||
|
* @param stateReaper FileStateReaper
|
||||||
|
*/
|
||||||
|
public final void enableStateTable(boolean ena, FileStateReaper stateReaper)
|
||||||
|
{
|
||||||
|
if ( ena == false)
|
||||||
|
{
|
||||||
|
// Remove the state table from the reaper
|
||||||
|
|
||||||
|
stateReaper.removeStateTable( getFilesystemName());
|
||||||
|
m_stateTable = null;
|
||||||
|
}
|
||||||
|
else if ( m_stateTable == null)
|
||||||
|
{
|
||||||
|
// Create the file state table
|
||||||
|
|
||||||
|
m_stateTable = new FileStateTable();
|
||||||
|
|
||||||
|
// Register with the file state reaper
|
||||||
|
|
||||||
|
stateReaper.addStateTable( getFilesystemName(), m_stateTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the reaper, for deregistering when the filesystem is closed
|
||||||
|
|
||||||
|
m_stateReaper = stateReaper;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@ import org.alfresco.config.ConfigElement;
|
|||||||
import org.alfresco.filesys.server.SrvSession;
|
import org.alfresco.filesys.server.SrvSession;
|
||||||
import org.alfresco.filesys.server.core.DeviceContext;
|
import org.alfresco.filesys.server.core.DeviceContext;
|
||||||
import org.alfresco.filesys.server.core.DeviceContextException;
|
import org.alfresco.filesys.server.core.DeviceContextException;
|
||||||
|
import org.alfresco.filesys.server.core.DeviceInterface;
|
||||||
import org.alfresco.filesys.server.filesys.AccessDeniedException;
|
import org.alfresco.filesys.server.filesys.AccessDeniedException;
|
||||||
import org.alfresco.filesys.server.filesys.DirectoryNotEmptyException;
|
import org.alfresco.filesys.server.filesys.DirectoryNotEmptyException;
|
||||||
import org.alfresco.filesys.server.filesys.DiskInterface;
|
import org.alfresco.filesys.server.filesys.DiskInterface;
|
||||||
@@ -40,6 +41,7 @@ import org.alfresco.filesys.server.filesys.FileStatus;
|
|||||||
import org.alfresco.filesys.server.filesys.NetworkFile;
|
import org.alfresco.filesys.server.filesys.NetworkFile;
|
||||||
import org.alfresco.filesys.server.filesys.SearchContext;
|
import org.alfresco.filesys.server.filesys.SearchContext;
|
||||||
import org.alfresco.filesys.server.filesys.TreeConnection;
|
import org.alfresco.filesys.server.filesys.TreeConnection;
|
||||||
|
import org.alfresco.filesys.server.state.FileStateReaper;
|
||||||
import org.alfresco.filesys.util.StringList;
|
import org.alfresco.filesys.util.StringList;
|
||||||
import org.alfresco.filesys.util.WildCard;
|
import org.alfresco.filesys.util.WildCard;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
@@ -93,6 +95,10 @@ public class AVMDiskDriver implements DiskInterface {
|
|||||||
|
|
||||||
private ServiceRegistry m_serviceRegistry;
|
private ServiceRegistry m_serviceRegistry;
|
||||||
|
|
||||||
|
// File state reaper
|
||||||
|
|
||||||
|
private FileStateReaper m_stateReaper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
@@ -140,6 +146,16 @@ public class AVMDiskDriver implements DiskInterface {
|
|||||||
return m_serviceRegistry;
|
return m_serviceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the file state reaper
|
||||||
|
*
|
||||||
|
* @return FileStateReaper
|
||||||
|
*/
|
||||||
|
public final FileStateReaper getStateReaper()
|
||||||
|
{
|
||||||
|
return m_stateReaper;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the AVM service
|
* Set the AVM service
|
||||||
*
|
*
|
||||||
@@ -200,15 +216,27 @@ public class AVMDiskDriver implements DiskInterface {
|
|||||||
m_mimetypeService = mimetypeService;
|
m_mimetypeService = mimetypeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the file state reaper
|
||||||
|
*
|
||||||
|
* @param stateReaper FileStateReaper
|
||||||
|
*/
|
||||||
|
public final void setStateReaper(FileStateReaper stateReaper)
|
||||||
|
{
|
||||||
|
m_stateReaper = stateReaper;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse and validate the parameter string and create a device context object for this instance
|
* Parse and validate the parameter string and create a device context object for this instance
|
||||||
* of the shared device.
|
* of the shared device.
|
||||||
*
|
*
|
||||||
|
* @param devIface DeviceInterface
|
||||||
|
* @param name String
|
||||||
* @param cfg ConfigElement
|
* @param cfg ConfigElement
|
||||||
* @return DeviceContext
|
* @return DeviceContext
|
||||||
* @exception DeviceContextException
|
* @exception DeviceContextException
|
||||||
*/
|
*/
|
||||||
public DeviceContext createContext(ConfigElement cfg)
|
public DeviceContext createContext(DeviceInterface devIface, String name, ConfigElement cfg)
|
||||||
throws DeviceContextException
|
throws DeviceContextException
|
||||||
{
|
{
|
||||||
// Use the system user as the authenticated context for the filesystem initialization
|
// Use the system user as the authenticated context for the filesystem initialization
|
||||||
@@ -315,7 +343,7 @@ public class AVMDiskDriver implements DiskInterface {
|
|||||||
|
|
||||||
// Create the context
|
// Create the context
|
||||||
|
|
||||||
context = new AVMContext(storePath, version);
|
context = new AVMContext( name, storePath, version);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -342,6 +370,10 @@ public class AVMDiskDriver implements DiskInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable file state caching
|
||||||
|
|
||||||
|
context.enableStateTable( true, getStateReaper());
|
||||||
|
|
||||||
// Return the context for this shared filesystem
|
// Return the context for this shared filesystem
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
|
238
source/java/org/alfresco/filesys/avm/AVMPath.java
Normal file
238
source/java/org/alfresco/filesys/avm/AVMPath.java
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 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.FileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AVM Path Class
|
||||||
|
*
|
||||||
|
* <p>Parses a share relative path into store, version and remaining path values.
|
||||||
|
*
|
||||||
|
* @author gkspencer
|
||||||
|
*/
|
||||||
|
public class AVMPath {
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
//
|
||||||
|
// Invalid version id value
|
||||||
|
|
||||||
|
private static final int InvalidVersionId = -2;
|
||||||
|
|
||||||
|
// Version id string for the head version
|
||||||
|
|
||||||
|
private static final String VersionNameHead = "Head";
|
||||||
|
|
||||||
|
// AVM path seperator
|
||||||
|
|
||||||
|
public static final char AVM_SEPERATOR = '/';
|
||||||
|
|
||||||
|
// Store name
|
||||||
|
|
||||||
|
private String m_storeName;
|
||||||
|
|
||||||
|
// Version id
|
||||||
|
|
||||||
|
private int m_version = InvalidVersionId;
|
||||||
|
|
||||||
|
// Remaining path
|
||||||
|
|
||||||
|
private String m_path;
|
||||||
|
|
||||||
|
// AVM style path
|
||||||
|
|
||||||
|
private String m_avmPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor
|
||||||
|
*
|
||||||
|
* @param shrPath String
|
||||||
|
*/
|
||||||
|
public AVMPath(String shrPath)
|
||||||
|
{
|
||||||
|
// Parse the path
|
||||||
|
|
||||||
|
parsePath( shrPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the store name
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public final String getStoreName()
|
||||||
|
{
|
||||||
|
return m_storeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the version id was specified in the path
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public final boolean hasVersion()
|
||||||
|
{
|
||||||
|
return m_version != InvalidVersionId ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the version id
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public final int getVersion()
|
||||||
|
{
|
||||||
|
return m_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the share relative path
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public final String getRelativePath()
|
||||||
|
{
|
||||||
|
return m_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the AVM style path, in <store>:/<path> format
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public final String getAVMPath()
|
||||||
|
{
|
||||||
|
return m_avmPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the path is valid
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public final boolean isValid()
|
||||||
|
{
|
||||||
|
return m_storeName == null ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the path
|
||||||
|
*
|
||||||
|
* @param path String
|
||||||
|
*/
|
||||||
|
private final void parsePath( String path)
|
||||||
|
{
|
||||||
|
// Split the path
|
||||||
|
|
||||||
|
String[] paths = FileName.splitAllPaths(path);
|
||||||
|
|
||||||
|
if ( paths == null || paths.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Set the store name
|
||||||
|
|
||||||
|
m_storeName = paths[0];
|
||||||
|
|
||||||
|
if ( paths.length > 1)
|
||||||
|
{
|
||||||
|
// Validate the version id
|
||||||
|
|
||||||
|
String verStr = paths[1];
|
||||||
|
if ( verStr.equalsIgnoreCase( VersionNameHead))
|
||||||
|
m_version = -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse the version id
|
||||||
|
|
||||||
|
m_version = Integer.parseInt( verStr);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
if ( paths.length > 2)
|
||||||
|
{
|
||||||
|
// Build the share relative path
|
||||||
|
|
||||||
|
StringBuilder pathStr = new StringBuilder();
|
||||||
|
|
||||||
|
for ( int i = 2; i < paths.length; i++)
|
||||||
|
{
|
||||||
|
pathStr.append( FileName.DOS_SEPERATOR);
|
||||||
|
pathStr.append( paths[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_path = pathStr.toString();
|
||||||
|
|
||||||
|
// Build the AVM path, in <store>:/<path> format
|
||||||
|
|
||||||
|
pathStr.setLength( 0);
|
||||||
|
|
||||||
|
pathStr.append( m_storeName);
|
||||||
|
pathStr.append( ":");
|
||||||
|
pathStr.append( m_path.replace( FileName.DOS_SEPERATOR, AVM_SEPERATOR));
|
||||||
|
|
||||||
|
m_avmPath = pathStr.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the AVM path details as a string
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
|
||||||
|
str.append("[");
|
||||||
|
str.append(getStoreName());
|
||||||
|
str.append(",");
|
||||||
|
|
||||||
|
if ( hasVersion())
|
||||||
|
str.append(getVersion());
|
||||||
|
else
|
||||||
|
str.append("NoVersion");
|
||||||
|
|
||||||
|
str.append(",");
|
||||||
|
str.append(getRelativePath());
|
||||||
|
str.append(":");
|
||||||
|
str.append(getAVMPath());
|
||||||
|
str.append("]");
|
||||||
|
|
||||||
|
return str.toString();
|
||||||
|
}
|
||||||
|
}
|
@@ -249,11 +249,8 @@ public class AVMShareMapper implements ShareMapper {
|
|||||||
|
|
||||||
// Create a dynamic share mapped to the AVM store/version
|
// Create a dynamic share mapped to the AVM store/version
|
||||||
|
|
||||||
DiskDeviceContext avmCtx = new AVMContext( storePath, storeVersion);
|
AVMContext avmCtx = new AVMContext( name, storePath, storeVersion);
|
||||||
|
avmCtx.enableStateTable( true, avmDrv.getStateReaper());
|
||||||
// Default the filesystem to look like an 80Gb sized disk with 90% free space
|
|
||||||
|
|
||||||
avmCtx.setDiskInformation(new SrvDiskInfo(2560, 64, 512, 2304));
|
|
||||||
|
|
||||||
// Create a dynamic shared device for the store version
|
// Create a dynamic shared device for the store version
|
||||||
|
|
||||||
|
@@ -3352,7 +3352,7 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
// Create the disk driver and context
|
// Create the disk driver and context
|
||||||
|
|
||||||
DiskInterface diskDrv = getServer().getConfiguration().getDiskInterface();
|
DiskInterface diskDrv = getServer().getConfiguration().getDiskInterface();
|
||||||
DiskDeviceContext diskCtx = new ContentContext("", "", client.getHomeFolder());
|
DiskDeviceContext diskCtx = new ContentContext( client.getUserName(), "", "", client.getHomeFolder());
|
||||||
|
|
||||||
// Default the filesystem to look like an 80Gb sized disk with 90% free space
|
// Default the filesystem to look like an 80Gb sized disk with 90% free space
|
||||||
|
|
||||||
|
@@ -836,7 +836,7 @@ public abstract class CifsAuthenticator
|
|||||||
// Create the disk driver and context
|
// Create the disk driver and context
|
||||||
|
|
||||||
DiskInterface diskDrv = m_config.getDiskInterface();
|
DiskInterface diskDrv = m_config.getDiskInterface();
|
||||||
DiskDeviceContext diskCtx = new ContentContext("", "", client.getHomeFolder());
|
DiskDeviceContext diskCtx = new ContentContext(client.getUserName(), "", "", client.getHomeFolder());
|
||||||
|
|
||||||
// Default the filesystem to look like an 80Gb sized disk with 90% free space
|
// Default the filesystem to look like an 80Gb sized disk with 90% free space
|
||||||
|
|
||||||
|
@@ -69,13 +69,13 @@ 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.filesys.HomeShareMapper;
|
|
||||||
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;
|
||||||
import org.alfresco.filesys.smb.server.repo.DesktopAction;
|
import org.alfresco.filesys.smb.server.repo.DesktopAction;
|
||||||
import org.alfresco.filesys.smb.server.repo.DesktopActionException;
|
import org.alfresco.filesys.smb.server.repo.DesktopActionException;
|
||||||
import org.alfresco.filesys.smb.server.repo.DesktopActionTable;
|
import org.alfresco.filesys.smb.server.repo.DesktopActionTable;
|
||||||
|
import org.alfresco.filesys.smb.server.repo.HomeShareMapper;
|
||||||
import org.alfresco.filesys.util.IPAddress;
|
import org.alfresco.filesys.util.IPAddress;
|
||||||
import org.alfresco.filesys.util.StringList;
|
import org.alfresco.filesys.util.StringList;
|
||||||
import org.alfresco.filesys.util.X64;
|
import org.alfresco.filesys.util.X64;
|
||||||
@@ -1692,11 +1692,16 @@ public class ServerConfiguration extends AbstractLifecycleBean
|
|||||||
// the new filesystem
|
// the new filesystem
|
||||||
|
|
||||||
DiskInterface filesysDriver = this.avmDiskInterface;
|
DiskInterface filesysDriver = this.avmDiskInterface;
|
||||||
AVMContext filesysContext = (AVMContext) filesysDriver.createContext(elem);
|
AVMContext filesysContext = (AVMContext) filesysDriver.createContext( filesysDriver, filesysName, elem);
|
||||||
|
filesysContext.setFilesystemName(filesysName);
|
||||||
|
|
||||||
// Create the shared filesystem
|
// Create the shared filesystem
|
||||||
|
|
||||||
filesys = new DiskSharedDevice(filesysName, filesysDriver, filesysContext);
|
filesys = new DiskSharedDevice(filesysName, filesysDriver, filesysContext);
|
||||||
|
|
||||||
|
// Start the filesystem
|
||||||
|
|
||||||
|
filesysContext.startFilesystem(filesys);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1704,7 +1709,7 @@ public class ServerConfiguration extends AbstractLifecycleBean
|
|||||||
// the new filesystem
|
// the new filesystem
|
||||||
|
|
||||||
DiskInterface filesysDriver = this.diskInterface;
|
DiskInterface filesysDriver = this.diskInterface;
|
||||||
ContentContext filesysContext = (ContentContext) filesysDriver.createContext(elem);
|
ContentContext filesysContext = (ContentContext) filesysDriver.createContext( filesysDriver, filesysName, elem);
|
||||||
|
|
||||||
// Check if an access control list has been specified
|
// Check if an access control list has been specified
|
||||||
|
|
||||||
@@ -1804,7 +1809,7 @@ public class ServerConfiguration extends AbstractLifecycleBean
|
|||||||
{
|
{
|
||||||
// Create the new share for the store
|
// Create the new share for the store
|
||||||
|
|
||||||
AVMContext avmContext = new AVMContext( storeName + ":/", AVMContext.VERSION_HEAD);
|
AVMContext avmContext = new AVMContext( storeName, storeName + ":/", AVMContext.VERSION_HEAD);
|
||||||
|
|
||||||
// Create the shared filesystem
|
// Create the shared filesystem
|
||||||
|
|
||||||
|
@@ -29,14 +29,17 @@ public class DeviceContext
|
|||||||
|
|
||||||
private String m_devName;
|
private String m_devName;
|
||||||
|
|
||||||
|
// Filesystem name
|
||||||
|
|
||||||
|
private String m_filesysName;
|
||||||
|
|
||||||
// Flag to indicate if the device is available. Unavailable devices will not be listed by the
|
// Flag to indicate if the device is available. Unavailable devices will not be listed by the
|
||||||
// various
|
// various protocol servers.
|
||||||
// protocol servers.
|
|
||||||
|
|
||||||
private boolean m_available = true;
|
private boolean m_available = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeviceContext constructor.
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
public DeviceContext()
|
public DeviceContext()
|
||||||
{
|
{
|
||||||
@@ -44,23 +47,37 @@ public class DeviceContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeviceContext constructor.
|
* Class constructor
|
||||||
|
*
|
||||||
|
* @param filesysName String
|
||||||
|
* @param devName String
|
||||||
*/
|
*/
|
||||||
public DeviceContext(String devName)
|
public DeviceContext(String filesysName, String devName)
|
||||||
{
|
{
|
||||||
m_devName = devName;
|
m_filesysName = filesysName;
|
||||||
|
m_devName = devName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the device name.
|
* Return the device name.
|
||||||
*
|
*
|
||||||
* @return java.lang.String
|
* @return String
|
||||||
*/
|
*/
|
||||||
public final String getDeviceName()
|
public final String getDeviceName()
|
||||||
{
|
{
|
||||||
return m_devName;
|
return m_devName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the filesystem name
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public final String getFilesystemName()
|
||||||
|
{
|
||||||
|
return m_filesysName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the filesystem is available
|
* Determine if the filesystem is available
|
||||||
*
|
*
|
||||||
@@ -84,13 +101,23 @@ public class DeviceContext
|
|||||||
/**
|
/**
|
||||||
* Set the device name.
|
* Set the device name.
|
||||||
*
|
*
|
||||||
* @param name java.lang.String
|
* @param name String
|
||||||
*/
|
*/
|
||||||
public final void setDeviceName(String name)
|
public final void setDeviceName(String name)
|
||||||
{
|
{
|
||||||
m_devName = name;
|
m_devName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the filesystem name
|
||||||
|
*
|
||||||
|
* @param filesysName String
|
||||||
|
*/
|
||||||
|
public final void setFilesystemName( String filesysName)
|
||||||
|
{
|
||||||
|
m_filesysName = filesysName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the device context, free any resources allocated by the context
|
* Close the device context, free any resources allocated by the context
|
||||||
*/
|
*/
|
||||||
@@ -108,6 +135,8 @@ public class DeviceContext
|
|||||||
StringBuffer str = new StringBuffer();
|
StringBuffer str = new StringBuffer();
|
||||||
|
|
||||||
str.append("[");
|
str.append("[");
|
||||||
|
str.append(getFilesystemName());
|
||||||
|
str.append(",");
|
||||||
str.append(getDeviceName());
|
str.append(getDeviceName());
|
||||||
str.append("]");
|
str.append("]");
|
||||||
|
|
||||||
|
@@ -32,11 +32,14 @@ public interface DeviceInterface
|
|||||||
* of the shared device. The same DeviceInterface implementation may be used for multiple
|
* of the shared device. The same DeviceInterface implementation may be used for multiple
|
||||||
* shares.
|
* shares.
|
||||||
*
|
*
|
||||||
|
* @param devIface DeviceInterface
|
||||||
|
* @param name String
|
||||||
* @param args ConfigElement
|
* @param args ConfigElement
|
||||||
* @return DeviceContext
|
* @return DeviceContext
|
||||||
* @exception DeviceContextException
|
* @exception DeviceContextException
|
||||||
*/
|
*/
|
||||||
public DeviceContext createContext(ConfigElement args) throws DeviceContextException;
|
public DeviceContext createContext(DeviceInterface devIface, String name, ConfigElement args)
|
||||||
|
throws DeviceContextException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection opened to this disk device
|
* Connection opened to this disk device
|
||||||
|
@@ -383,7 +383,7 @@ public class SharedDevice implements Comparable
|
|||||||
*/
|
*/
|
||||||
public DeviceContext createContext(String[] args)
|
public DeviceContext createContext(String[] args)
|
||||||
{
|
{
|
||||||
return new DeviceContext(args[0]);
|
return new DeviceContext("", args[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -59,11 +59,12 @@ public class DiskDeviceContext extends DeviceContext
|
|||||||
/**
|
/**
|
||||||
* Class constructor
|
* Class constructor
|
||||||
*
|
*
|
||||||
|
* @param filesysName String
|
||||||
* @param devName String
|
* @param devName String
|
||||||
*/
|
*/
|
||||||
public DiskDeviceContext(String devName)
|
public DiskDeviceContext(String filesysName, String devName)
|
||||||
{
|
{
|
||||||
super(devName);
|
super(filesysName, devName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
* language governing permissions and limitations under the
|
* language governing permissions and limitations under the
|
||||||
* License.
|
* License.
|
||||||
*/
|
*/
|
||||||
package org.alfresco.filesys.smb.server.repo;
|
package org.alfresco.filesys.server.state;
|
||||||
|
|
||||||
import org.alfresco.filesys.locking.FileLock;
|
import org.alfresco.filesys.locking.FileLock;
|
||||||
import org.alfresco.filesys.locking.FileLockList;
|
import org.alfresco.filesys.locking.FileLockList;
|
@@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 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.server.state;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File State Reaper Class
|
||||||
|
*
|
||||||
|
* <p>FileStateTable objects register with the file state reaper to periodically check for expired file states.
|
||||||
|
*
|
||||||
|
* @author gkspencer
|
||||||
|
*/
|
||||||
|
public class FileStateReaper implements Runnable {
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(FileStateReaper.class);
|
||||||
|
|
||||||
|
// Default expire check thread interval
|
||||||
|
|
||||||
|
private static final long DEFAULT_EXPIRECHECK = 15000;
|
||||||
|
|
||||||
|
// Wakeup interval for the expire file state checker thread
|
||||||
|
|
||||||
|
private long m_expireInterval = DEFAULT_EXPIRECHECK;
|
||||||
|
|
||||||
|
// File state checker thread
|
||||||
|
|
||||||
|
private Thread m_thread;
|
||||||
|
|
||||||
|
// Shutdown request flag
|
||||||
|
|
||||||
|
private boolean m_shutdown;
|
||||||
|
|
||||||
|
// List of file state tables to be scanned for expired file states
|
||||||
|
|
||||||
|
private Hashtable<String, FileStateTable> m_stateTables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
public FileStateReaper()
|
||||||
|
{
|
||||||
|
// Create the reaper thread
|
||||||
|
|
||||||
|
m_thread = new Thread(this);
|
||||||
|
m_thread.setDaemon(true);
|
||||||
|
m_thread.setName("FileStateReaper");
|
||||||
|
m_thread.start();
|
||||||
|
|
||||||
|
// Create the file state table list
|
||||||
|
|
||||||
|
m_stateTables = new Hashtable<String, FileStateTable>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the expired file state checker interval, in milliseconds
|
||||||
|
*
|
||||||
|
* @return long
|
||||||
|
*/
|
||||||
|
public final long getCheckInterval()
|
||||||
|
{
|
||||||
|
return m_expireInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the expired file state checker interval, in milliseconds
|
||||||
|
*
|
||||||
|
* @param chkIntval long
|
||||||
|
*/
|
||||||
|
public final void setCheckInterval(long chkIntval)
|
||||||
|
{
|
||||||
|
m_expireInterval = chkIntval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a file state table to the reaper list
|
||||||
|
*
|
||||||
|
* @param filesysName String
|
||||||
|
* @param stateTable FileStateTable
|
||||||
|
*/
|
||||||
|
public final void addStateTable( String filesysName, FileStateTable stateTable)
|
||||||
|
{
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug( "Added file state table for " + filesysName);
|
||||||
|
|
||||||
|
m_stateTables.put( filesysName, stateTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a state table from the reaper list
|
||||||
|
*
|
||||||
|
* @param filesysName String
|
||||||
|
*/
|
||||||
|
public final void removeStateTable( String filesysName)
|
||||||
|
{
|
||||||
|
m_stateTables.remove( filesysName);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug( "Removed file state table for " + filesysName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expired file state checker thread
|
||||||
|
*/
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
// Loop forever
|
||||||
|
|
||||||
|
m_shutdown = false;
|
||||||
|
|
||||||
|
while ( m_shutdown == false)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Sleep for the required interval
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(getCheckInterval());
|
||||||
|
}
|
||||||
|
catch (InterruptedException ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for shutdown
|
||||||
|
|
||||||
|
if ( m_shutdown == true)
|
||||||
|
{
|
||||||
|
// Debug
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("FileStateReaper thread closing");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there are any state tables registered
|
||||||
|
|
||||||
|
if ( m_stateTables != null && m_stateTables.size() > 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Loop through the registered file state tables and remove expired file states
|
||||||
|
|
||||||
|
Enumeration<String> filesysNames = m_stateTables.keys();
|
||||||
|
|
||||||
|
while ( filesysNames.hasMoreElements())
|
||||||
|
{
|
||||||
|
// Get the current filesystem name and associated state table
|
||||||
|
|
||||||
|
String filesysName = filesysNames.nextElement();
|
||||||
|
FileStateTable stateTable = m_stateTables.get( filesysName);
|
||||||
|
|
||||||
|
// Check for expired file states
|
||||||
|
|
||||||
|
int cnt = stateTable.removeExpiredFileStates();
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled() && cnt > 0)
|
||||||
|
logger.debug("Expired " + cnt + " file states for " + filesysName + ", cache=" + stateTable.numberOfStates());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Log errors if not shutting down
|
||||||
|
|
||||||
|
if ( m_shutdown == false)
|
||||||
|
logger.debug(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the file state checker thread to shutdown
|
||||||
|
*/
|
||||||
|
public final void shutdownRequest() {
|
||||||
|
m_shutdown = true;
|
||||||
|
|
||||||
|
if ( m_thread != null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
m_thread.interrupt();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -14,19 +14,20 @@
|
|||||||
* language governing permissions and limitations under the
|
* language governing permissions and limitations under the
|
||||||
* License.
|
* License.
|
||||||
*/
|
*/
|
||||||
package org.alfresco.filesys.smb.server.repo;
|
package org.alfresco.filesys.server.state;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.*;
|
import org.apache.commons.logging.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File State Table Class
|
* File State Table Class
|
||||||
* <p>
|
*
|
||||||
* Contains an indexed list of the currently open files/folders.
|
* <p>Contains an indexed list of the currently open files/folders.
|
||||||
|
*
|
||||||
|
* @author gkspencer
|
||||||
*/
|
*/
|
||||||
public class FileStateTable implements Runnable
|
public class FileStateTable
|
||||||
{
|
{
|
||||||
private static final Log logger = LogFactory.getLog(FileStateTable.class);
|
private static final Log logger = LogFactory.getLog(FileStateTable.class);
|
||||||
|
|
||||||
@@ -34,30 +35,14 @@ public class FileStateTable implements Runnable
|
|||||||
|
|
||||||
private static final int INITIAL_SIZE = 100;
|
private static final int INITIAL_SIZE = 100;
|
||||||
|
|
||||||
// Default expire check thread interval
|
|
||||||
|
|
||||||
private static final long DEFAULT_EXPIRECHECK = 15000;
|
|
||||||
|
|
||||||
// File state table, keyed by file path
|
// File state table, keyed by file path
|
||||||
|
|
||||||
private Hashtable<String, FileState> m_stateTable;
|
private Hashtable<String, FileState> m_stateTable;
|
||||||
|
|
||||||
// Wakeup interval for the expire file state checker thread
|
|
||||||
|
|
||||||
private long m_expireInterval = DEFAULT_EXPIRECHECK;
|
|
||||||
|
|
||||||
// File state expiry time in seconds
|
// File state expiry time in seconds
|
||||||
|
|
||||||
private long m_cacheTimer = 2 * 60000L; // 2 minutes default
|
private long m_cacheTimer = 2 * 60000L; // 2 minutes default
|
||||||
|
|
||||||
// File state checker thread
|
|
||||||
|
|
||||||
private Thread m_thread;
|
|
||||||
|
|
||||||
// Shutdown request flag
|
|
||||||
|
|
||||||
private boolean m_shutdown;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class constructor
|
* Class constructor
|
||||||
*/
|
*/
|
||||||
@@ -67,20 +52,6 @@ public class FileStateTable implements Runnable
|
|||||||
|
|
||||||
// Start the expired file state checker thread
|
// Start the expired file state checker thread
|
||||||
|
|
||||||
m_thread = new Thread(this);
|
|
||||||
m_thread.setDaemon(true);
|
|
||||||
m_thread.setName("FileStateExpire");
|
|
||||||
m_thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the expired file state checker interval, in milliseconds
|
|
||||||
*
|
|
||||||
* @return long
|
|
||||||
*/
|
|
||||||
public final long getCheckInterval()
|
|
||||||
{
|
|
||||||
return m_expireInterval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,16 +84,6 @@ public class FileStateTable implements Runnable
|
|||||||
m_cacheTimer = tmo;
|
m_cacheTimer = tmo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the expired file state checker interval, in milliseconds
|
|
||||||
*
|
|
||||||
* @param chkIntval long
|
|
||||||
*/
|
|
||||||
public final void setCheckInterval(long chkIntval)
|
|
||||||
{
|
|
||||||
m_expireInterval = chkIntval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new file state
|
* Add a new file state
|
||||||
*
|
*
|
||||||
@@ -351,7 +312,7 @@ public class FileStateTable implements Runnable
|
|||||||
// DEBUG
|
// DEBUG
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("++ Expired file state: " + state);
|
logger.debug("Expired file state: " + state);
|
||||||
|
|
||||||
// Update the expired count
|
// Update the expired count
|
||||||
|
|
||||||
@@ -366,79 +327,6 @@ public class FileStateTable implements Runnable
|
|||||||
return expiredCnt;
|
return expiredCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Expired file state checker thread
|
|
||||||
*/
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
|
|
||||||
// Loop forever
|
|
||||||
|
|
||||||
m_shutdown = false;
|
|
||||||
|
|
||||||
while ( m_shutdown == false)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Sleep for the required interval
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Thread.sleep(getCheckInterval());
|
|
||||||
}
|
|
||||||
catch (InterruptedException ex)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for shutdown
|
|
||||||
|
|
||||||
if ( m_shutdown == true)
|
|
||||||
{
|
|
||||||
// Debug
|
|
||||||
|
|
||||||
if ( logger.isDebugEnabled())
|
|
||||||
logger.debug("FileStateExpire thread closing");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
// Check for expired file states
|
|
||||||
|
|
||||||
int cnt = removeExpiredFileStates();
|
|
||||||
|
|
||||||
// Debug
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled() && cnt > 0)
|
|
||||||
{
|
|
||||||
logger.debug("++ Expired " + cnt + " file states, cache=" + m_stateTable.size());
|
|
||||||
Dump();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
logger.debug(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request the file state checker thread to shutdown
|
|
||||||
*/
|
|
||||||
public final void shutdownRequest() {
|
|
||||||
m_shutdown = true;
|
|
||||||
|
|
||||||
if ( m_thread != null)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
m_thread.interrupt();
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump the state cache entries to the specified stream
|
* Dump the state cache entries to the specified stream
|
||||||
*/
|
*/
|
||||||
@@ -448,7 +336,7 @@ public class FileStateTable implements Runnable
|
|||||||
// Dump the file state cache entries to the specified stream
|
// Dump the file state cache entries to the specified stream
|
||||||
|
|
||||||
if (m_stateTable.size() > 0)
|
if (m_stateTable.size() > 0)
|
||||||
logger.debug("++ FileStateCache Entries:");
|
logger.debug("FileStateCache Entries:");
|
||||||
|
|
||||||
Enumeration enm = m_stateTable.keys();
|
Enumeration enm = m_stateTable.keys();
|
||||||
long curTime = System.currentTimeMillis();
|
long curTime = System.currentTimeMillis();
|
||||||
@@ -458,7 +346,7 @@ public class FileStateTable implements Runnable
|
|||||||
String fname = (String) enm.nextElement();
|
String fname = (String) enm.nextElement();
|
||||||
FileState state = m_stateTable.get(fname);
|
FileState state = m_stateTable.get(fname);
|
||||||
|
|
||||||
logger.debug(" ++ " + fname + "(" + state.getSecondsToExpire(curTime) + ") : " + state);
|
logger.debug(" " + fname + "(" + state.getSecondsToExpire(curTime) + ") : " + state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -19,6 +19,8 @@ package org.alfresco.filesys.smb.server.repo;
|
|||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
|
||||||
import org.alfresco.filesys.server.filesys.*;
|
import org.alfresco.filesys.server.filesys.*;
|
||||||
|
import org.alfresco.filesys.server.state.FileStateReaper;
|
||||||
|
import org.alfresco.filesys.server.state.FileStateTable;
|
||||||
import org.alfresco.filesys.smb.server.repo.pseudo.ContentPseudoFileImpl;
|
import org.alfresco.filesys.smb.server.repo.pseudo.ContentPseudoFileImpl;
|
||||||
import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFileInterface;
|
import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFileInterface;
|
||||||
import org.alfresco.service.cmr.repository.*;
|
import org.alfresco.service.cmr.repository.*;
|
||||||
@@ -41,9 +43,10 @@ public class ContentContext extends DiskDeviceContext
|
|||||||
|
|
||||||
private NodeRef m_rootNodeRef;
|
private NodeRef m_rootNodeRef;
|
||||||
|
|
||||||
// File state table
|
// File state table and associated file state reaper
|
||||||
|
|
||||||
private FileStateTable m_stateTable;
|
private FileStateTable m_stateTable;
|
||||||
|
private FileStateReaper m_stateReaper;
|
||||||
|
|
||||||
// URL pseudo file web path prefix (server/port/webapp) and link file name
|
// URL pseudo file web path prefix (server/port/webapp) and link file name
|
||||||
|
|
||||||
@@ -65,13 +68,14 @@ public class ContentContext extends DiskDeviceContext
|
|||||||
/**
|
/**
|
||||||
* Class constructor
|
* Class constructor
|
||||||
*
|
*
|
||||||
|
*@param filesysName String
|
||||||
* @param storeName String
|
* @param storeName String
|
||||||
* @param rootPath String
|
* @param rootPath String
|
||||||
* @param rootNodeRef NodeRef
|
* @param rootNodeRef NodeRef
|
||||||
*/
|
*/
|
||||||
public ContentContext(String storeName, String rootPath, NodeRef rootNodeRef)
|
public ContentContext(String filesysName, String storeName, String rootPath, NodeRef rootNodeRef)
|
||||||
{
|
{
|
||||||
super(rootNodeRef.toString());
|
super(filesysName, rootNodeRef.toString());
|
||||||
|
|
||||||
m_storeName = storeName;
|
m_storeName = storeName;
|
||||||
m_rootPath = rootPath;
|
m_rootPath = rootPath;
|
||||||
@@ -147,13 +151,31 @@ public class ContentContext extends DiskDeviceContext
|
|||||||
* Enable/disable the file state table
|
* Enable/disable the file state table
|
||||||
*
|
*
|
||||||
* @param ena boolean
|
* @param ena boolean
|
||||||
|
* @param stateReaper FileStateReaper
|
||||||
*/
|
*/
|
||||||
public final void enableStateTable(boolean ena)
|
public final void enableStateTable(boolean ena, FileStateReaper stateReaper)
|
||||||
{
|
{
|
||||||
if ( ena == false)
|
if ( ena == false)
|
||||||
|
{
|
||||||
|
// Remove the state table from the reaper
|
||||||
|
|
||||||
|
stateReaper.removeStateTable( getFilesystemName());
|
||||||
m_stateTable = null;
|
m_stateTable = null;
|
||||||
|
}
|
||||||
else if ( m_stateTable == null)
|
else if ( m_stateTable == null)
|
||||||
|
{
|
||||||
|
// Create the file state table
|
||||||
|
|
||||||
m_stateTable = new FileStateTable();
|
m_stateTable = new FileStateTable();
|
||||||
|
|
||||||
|
// Register with the file state reaper
|
||||||
|
|
||||||
|
stateReaper.addStateTable( getFilesystemName(), m_stateTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the reaper, for deregistering when the filesystem is closed
|
||||||
|
|
||||||
|
m_stateReaper = stateReaper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -354,14 +376,10 @@ public class ContentContext extends DiskDeviceContext
|
|||||||
*/
|
*/
|
||||||
public void CloseContext() {
|
public void CloseContext() {
|
||||||
|
|
||||||
// Check if file states are enabled
|
// Deregister the file state table from the reaper
|
||||||
|
|
||||||
if ( hasStateTable())
|
if ( m_stateTable != null)
|
||||||
{
|
enableStateTable( false, m_stateReaper);
|
||||||
// Shutdown the file state checker thread
|
|
||||||
|
|
||||||
getStateTable().shutdownRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the base class
|
// Call the base class
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
|||||||
import org.alfresco.filesys.server.SrvSession;
|
import org.alfresco.filesys.server.SrvSession;
|
||||||
import org.alfresco.filesys.server.core.DeviceContext;
|
import org.alfresco.filesys.server.core.DeviceContext;
|
||||||
import org.alfresco.filesys.server.core.DeviceContextException;
|
import org.alfresco.filesys.server.core.DeviceContextException;
|
||||||
|
import org.alfresco.filesys.server.core.DeviceInterface;
|
||||||
import org.alfresco.filesys.server.filesys.AccessDeniedException;
|
import org.alfresco.filesys.server.filesys.AccessDeniedException;
|
||||||
import org.alfresco.filesys.server.filesys.AccessMode;
|
import org.alfresco.filesys.server.filesys.AccessMode;
|
||||||
import org.alfresco.filesys.server.filesys.DiskInterface;
|
import org.alfresco.filesys.server.filesys.DiskInterface;
|
||||||
@@ -44,11 +45,13 @@ import org.alfresco.filesys.server.filesys.NetworkFile;
|
|||||||
import org.alfresco.filesys.server.filesys.SearchContext;
|
import org.alfresco.filesys.server.filesys.SearchContext;
|
||||||
import org.alfresco.filesys.server.filesys.SrvDiskInfo;
|
import org.alfresco.filesys.server.filesys.SrvDiskInfo;
|
||||||
import org.alfresco.filesys.server.filesys.TreeConnection;
|
import org.alfresco.filesys.server.filesys.TreeConnection;
|
||||||
|
import org.alfresco.filesys.server.state.FileState;
|
||||||
|
import org.alfresco.filesys.server.state.FileStateReaper;
|
||||||
|
import org.alfresco.filesys.server.state.FileState.FileStateStatus;
|
||||||
import org.alfresco.filesys.smb.SMBException;
|
import org.alfresco.filesys.smb.SMBException;
|
||||||
import org.alfresco.filesys.smb.SMBStatus;
|
import org.alfresco.filesys.smb.SMBStatus;
|
||||||
import org.alfresco.filesys.smb.SharingMode;
|
import org.alfresco.filesys.smb.SharingMode;
|
||||||
import org.alfresco.filesys.smb.server.SMBSrvSession;
|
import org.alfresco.filesys.smb.server.SMBSrvSession;
|
||||||
import org.alfresco.filesys.smb.server.repo.FileState.FileStateStatus;
|
|
||||||
import org.alfresco.filesys.smb.server.repo.pseudo.MemoryNetworkFile;
|
import org.alfresco.filesys.smb.server.repo.pseudo.MemoryNetworkFile;
|
||||||
import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFile;
|
import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFile;
|
||||||
import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFileInterface;
|
import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFileInterface;
|
||||||
@@ -113,6 +116,10 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
|||||||
|
|
||||||
private ServiceRegistry serviceRegistry;
|
private ServiceRegistry serviceRegistry;
|
||||||
|
|
||||||
|
// File state reaper
|
||||||
|
|
||||||
|
private FileStateReaper m_stateReaper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class constructor
|
* Class constructor
|
||||||
*
|
*
|
||||||
@@ -202,6 +209,16 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
|||||||
return this.serviceRegistry;
|
return this.serviceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the file state reaper
|
||||||
|
*
|
||||||
|
* @return FileStateReaper
|
||||||
|
*/
|
||||||
|
public final FileStateReaper getStateReaper()
|
||||||
|
{
|
||||||
|
return m_stateReaper;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param contentService the content service
|
* @param contentService the content service
|
||||||
*/
|
*/
|
||||||
@@ -282,16 +299,28 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
|||||||
this.authService = authService;
|
this.authService = authService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the file state reaper
|
||||||
|
*
|
||||||
|
* @param stateReaper FileStateReaper
|
||||||
|
*/
|
||||||
|
public final void setStateReaper(FileStateReaper stateReaper)
|
||||||
|
{
|
||||||
|
m_stateReaper = stateReaper;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse and validate the parameter string and create a device context object for this instance
|
* Parse and validate the parameter string and create a device context object for this instance
|
||||||
* of the shared device. The same DeviceInterface implementation may be used for multiple
|
* of the shared device. The same DeviceInterface implementation may be used for multiple
|
||||||
* shares.
|
* shares.
|
||||||
*
|
*
|
||||||
|
* @param devIface DeviceInterface
|
||||||
|
* @param name String
|
||||||
* @param args ConfigElement
|
* @param args ConfigElement
|
||||||
* @return DeviceContext
|
* @return DeviceContext
|
||||||
* @exception DeviceContextException
|
* @exception DeviceContextException
|
||||||
*/
|
*/
|
||||||
public DeviceContext createContext(ConfigElement cfg) throws DeviceContextException
|
public DeviceContext createContext(DeviceInterface devIface, String name, ConfigElement cfg) throws DeviceContextException
|
||||||
{
|
{
|
||||||
// Use the system user as the authenticated context for the filesystem initialization
|
// Use the system user as the authenticated context for the filesystem initialization
|
||||||
|
|
||||||
@@ -389,7 +418,7 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
|||||||
|
|
||||||
// Create the context
|
// Create the context
|
||||||
|
|
||||||
context = new ContentContext(storeValue, rootPath, rootNodeRef);
|
context = new ContentContext(name, storeValue, rootPath, rootNodeRef);
|
||||||
|
|
||||||
// Default the filesystem to look like an 80Gb sized disk with 90% free space
|
// Default the filesystem to look like an 80Gb sized disk with 90% free space
|
||||||
|
|
||||||
@@ -497,6 +526,10 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
|||||||
logger.info("Locked files will be marked as offline");
|
logger.info("Locked files will be marked as offline");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable file state caching
|
||||||
|
|
||||||
|
context.enableStateTable( true, getStateReaper());
|
||||||
|
|
||||||
// Return the context for this shared filesystem
|
// Return the context for this shared filesystem
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* License.
|
* License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.alfresco.filesys.server.filesys;
|
package org.alfresco.filesys.smb.server.repo;
|
||||||
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
|
||||||
@@ -29,7 +29,9 @@ import org.alfresco.filesys.server.core.ShareMapper;
|
|||||||
import org.alfresco.filesys.server.core.ShareType;
|
import org.alfresco.filesys.server.core.ShareType;
|
||||||
import org.alfresco.filesys.server.core.SharedDevice;
|
import org.alfresco.filesys.server.core.SharedDevice;
|
||||||
import org.alfresco.filesys.server.core.SharedDeviceList;
|
import org.alfresco.filesys.server.core.SharedDeviceList;
|
||||||
|
import org.alfresco.filesys.server.filesys.DiskSharedDevice;
|
||||||
import org.alfresco.filesys.smb.server.repo.ContentContext;
|
import org.alfresco.filesys.smb.server.repo.ContentContext;
|
||||||
|
import org.alfresco.filesys.smb.server.repo.ContentDiskDriver;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -317,12 +319,10 @@ public class HomeShareMapper implements ShareMapper
|
|||||||
{
|
{
|
||||||
// Create the disk driver and context
|
// Create the disk driver and context
|
||||||
|
|
||||||
DiskInterface diskDrv = m_config.getDiskInterface();
|
ContentDiskDriver diskDrv = ( ContentDiskDriver) m_config.getDiskInterface();
|
||||||
DiskDeviceContext diskCtx = new ContentContext("", "", client.getHomeFolder());
|
ContentContext diskCtx = new ContentContext( getHomeFolderName(), "", "", client.getHomeFolder());
|
||||||
|
|
||||||
// Default the filesystem to look like an 80Gb sized disk with 90% free space
|
diskCtx.enableStateTable( true, diskDrv.getStateReaper());
|
||||||
|
|
||||||
diskCtx.setDiskInformation(new SrvDiskInfo(2560, 64, 512, 2304));
|
|
||||||
|
|
||||||
// Create a temporary shared device for the users home directory
|
// Create a temporary shared device for the users home directory
|
||||||
|
|
@@ -21,11 +21,11 @@ import java.util.Enumeration;
|
|||||||
import org.alfresco.filesys.server.SrvSession;
|
import org.alfresco.filesys.server.SrvSession;
|
||||||
import org.alfresco.filesys.server.filesys.FileName;
|
import org.alfresco.filesys.server.filesys.FileName;
|
||||||
import org.alfresco.filesys.server.filesys.TreeConnection;
|
import org.alfresco.filesys.server.filesys.TreeConnection;
|
||||||
|
import org.alfresco.filesys.server.state.FileState;
|
||||||
import org.alfresco.filesys.smb.server.SMBSrvSession;
|
import org.alfresco.filesys.smb.server.SMBSrvSession;
|
||||||
import org.alfresco.filesys.smb.server.repo.ContentContext;
|
import org.alfresco.filesys.smb.server.repo.ContentContext;
|
||||||
import org.alfresco.filesys.smb.server.repo.DesktopAction;
|
import org.alfresco.filesys.smb.server.repo.DesktopAction;
|
||||||
import org.alfresco.filesys.smb.server.repo.DesktopActionTable;
|
import org.alfresco.filesys.smb.server.repo.DesktopActionTable;
|
||||||
import org.alfresco.filesys.smb.server.repo.FileState;
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user