mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merge 3.1 to HEAD:
13314: Fix for CIFS offline sync, reconnect updated file to properties/history. ETHREEOH-1247. 13334: Added attribute to allow CIFS host announcement to be switched off via custom config. ETHREEOH-1356. Fixed bug in Windows domain name config. 13335: Changed error message to warning, and removed stacktrace, when resolving the server name. 13336: Renamed file-servers-custom.xml out of the way, to .sample2. Seems to be from an Adobe merge. 13377: Hack to enable basic CIFS IPv6 support, enabled via <tcpipSMB ipv6="enabled"/> in the xml config file. 13399: Fixed confusing debug message. 13431: Added missing parsing of 'offlineCheckInterval' parameter. 13457: Added support for file locking on in-memory pseudo files. Fix for problem with __AlfrescoClient.url files ETHREEOH-1311 13485: Added the missing CIFS sessionTimeout config value parsing. 13521: Updated file-servers.xml default config to match previous file-servers-custom.xml settings git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13762 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -4,42 +4,91 @@
|
||||
<!-- add additional filesystems remove the replace="true" attribute -->
|
||||
|
||||
<config evaluator="string-compare" condition="Filesystems" replace="true">
|
||||
|
||||
<filesystems>
|
||||
|
||||
<!-- Default share -->
|
||||
<filesystem name="Alfresco">
|
||||
|
||||
<!-- Alfresco repository access shared filesystem -->
|
||||
<filesystem name="${filesystem.name}">
|
||||
<store>workspace://SpacesStore</store>
|
||||
<rootPath>/app:company_home</rootPath>
|
||||
|
||||
<!-- Enable Web client launch shortcut in all folders -->
|
||||
<!-- Add a URL file to each folder that links back to the web client -->
|
||||
<urlFile>
|
||||
|
||||
<!-- Change the filename as required, keeping the .url extension -->
|
||||
<filename>_Alfresco.url</filename>
|
||||
|
||||
<!-- Change 'localhost' to the name or IP of the Alfresco server -->
|
||||
<webpath>http://localhost:8080/alfresco/</webpath>
|
||||
|
||||
<filename>__Alfresco.url</filename>
|
||||
<webpath>http://${localname}:8080/alfresco/</webpath>
|
||||
</urlFile>
|
||||
|
||||
</filesystem>
|
||||
</filesystems>
|
||||
<!-- Mark locked files as offline -->
|
||||
<offlineFiles/>
|
||||
|
||||
</config>
|
||||
<!-- Desktop actions -->
|
||||
<!-- Uses a client-side application to trigger a server-side action -->
|
||||
<!-- Echo - displays a message echoed from the server -->
|
||||
<!-- URL - launches a URL via the Windows shell -->
|
||||
<!-- CmdLine - launches the Notepad application -->
|
||||
<!-- CheckInOut - checks files in/out, drag and drop files onto the application -->
|
||||
<!-- JavaScript - run a server-side script -->
|
||||
<!-- JavaScriptURL - server-side script that generates a URL to the folder using a ticket -->
|
||||
<!-- to avoid having to logon -->
|
||||
|
||||
<!-- Allow guest access to file systems -->
|
||||
<config evaluator="string-compare" condition="Filesystem Security">
|
||||
<desktopActions>
|
||||
<global>
|
||||
<path>alfresco/desktop/Alfresco.exe</path>
|
||||
<webpath>http://${localname}:8080/alfresco/</webpath>
|
||||
</global>
|
||||
<action>
|
||||
<class>org.alfresco.filesys.repo.desk.CheckInOutDesktopAction</class>
|
||||
<name>CheckInOut</name>
|
||||
<filename>__CheckInOut.exe</filename>
|
||||
</action>
|
||||
<action>
|
||||
<class>org.alfresco.filesys.repo.desk.JavaScriptDesktopAction</class>
|
||||
<name>JavaScriptURL</name>
|
||||
<filename>__ShowDetails.exe</filename>
|
||||
<script>alfresco/desktop/showDetails.js</script>
|
||||
<attributes>anyFiles</attributes>
|
||||
<preprocess>copyToTarget</preprocess>
|
||||
</action>
|
||||
<action>
|
||||
<class>org.alfresco.filesys.repo.desk.EchoDesktopAction</class>
|
||||
<name>Echo</name>
|
||||
<filename>__AlfrescoEcho.exe</filename>
|
||||
</action>
|
||||
<action>
|
||||
<class>org.alfresco.filesys.repo.desk.URLDesktopAction</class>
|
||||
<name>URL</name>
|
||||
<filename>__AlfrescoURL.exe</filename>
|
||||
</action>
|
||||
<action>
|
||||
<class>org.alfresco.filesys.repo.desk.CmdLineDesktopAction</class>
|
||||
<name>CmdLine</name>
|
||||
<filename>__AlfrescoCmd.exe</filename>
|
||||
</action>
|
||||
<action>
|
||||
<class>org.alfresco.filesys.repo.desk.JavaScriptDesktopAction</class>
|
||||
<name>JavaScript</name>
|
||||
<filename>__AlfrescoScript.exe</filename>
|
||||
<script>alfresco/desktop/dumpRequest.js</script>
|
||||
<attributes>anyFiles, multiplePaths , allowNoParams</attributes>
|
||||
<preprocess>confirm, copyToTarget</preprocess>
|
||||
</action>
|
||||
</desktopActions>
|
||||
|
||||
<authenticator type="alfresco">
|
||||
<allowGuest/>
|
||||
<!-- Map any unknown user to guest -->
|
||||
<!-- Additional access control of the filesystem -->
|
||||
<!-- Access type of 'none' will stop the filesystem from showing up for that user/address/protocol -->
|
||||
<!--
|
||||
<mapUnknownUserToGuest/>
|
||||
<accessControl default="Write">
|
||||
<user name="admin" access="Write"/>
|
||||
<address subnet="192.168.1.0" mask="255.255.255.0" access="Write"/>
|
||||
</accessControl>
|
||||
-->
|
||||
</authenticator>
|
||||
</filesystem>
|
||||
|
||||
<!-- AVM virtualization view of all stores/versions for WCM -->
|
||||
<!-- virtual view can be any of the following: normal, site, staging, author, preview -->
|
||||
<avmfilesystem name="AVM">
|
||||
<virtualView stores="site,staging,author"/>
|
||||
</avmfilesystem>
|
||||
|
||||
</filesystems>
|
||||
</config>
|
||||
|
||||
</alfresco-config>
|
||||
|
@@ -86,6 +86,7 @@
|
||||
<property name="serviceRegistry"><ref bean="ServiceRegistry"/></property>
|
||||
<property name="stateReaper"><ref bean="fileStateReaper"/></property>
|
||||
<property name="nodeMonitorFactory"><ref bean="nodeMonitorFactory"/></property>
|
||||
<property name="nodeArchiveService"><ref bean="nodeArchiveService" /></property>
|
||||
</bean>
|
||||
|
||||
<bean id="nodeMonitorFactory" class="org.alfresco.filesys.repo.NodeMonitorFactory">
|
||||
|
@@ -192,6 +192,10 @@ public class ServerConfigurationBean extends ServerConfiguration implements Appl
|
||||
private static final int MemoryPoolMinimumAllocation = 5;
|
||||
private static final int MemoryPoolMaximumAllocation = 500;
|
||||
|
||||
// Maximum session timeout
|
||||
|
||||
private static final int MaxSessionTimeout = 60 * 60; // 1 hour
|
||||
|
||||
// Authentication manager
|
||||
|
||||
private AuthenticationManager m_authenticationManager;
|
||||
@@ -935,7 +939,21 @@ public class ServerConfigurationBean extends ServerConfiguration implements Appl
|
||||
elem = config.getConfigElement("hostAnnounce");
|
||||
if (elem != null)
|
||||
{
|
||||
// Check if the host announcer has been disabled
|
||||
|
||||
String enabled = elem.getAttribute("enabled");
|
||||
if ( enabled != null && enabled.equalsIgnoreCase( "false"))
|
||||
{
|
||||
// Switch off the host announcer
|
||||
|
||||
cifsConfig.setHostAnnouncer( false);
|
||||
|
||||
// Log that host announcements are not enabled
|
||||
|
||||
logger.info("Host announcements not enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for an announcement interval
|
||||
|
||||
String interval = elem.getAttribute("interval");
|
||||
@@ -961,6 +979,7 @@ public class ServerConfigurationBean extends ServerConfiguration implements Appl
|
||||
|
||||
cifsConfig.setHostAnnouncer(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if NetBIOS SMB is enabled
|
||||
|
||||
@@ -1273,6 +1292,28 @@ public class ServerConfigurationBean extends ServerConfiguration implements Appl
|
||||
throw new AlfrescoRuntimeException("Invalid TCP/IP SMB port");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if IPv6 support should be enabled
|
||||
|
||||
String ipv6 = elem.getAttribute("ipv6");
|
||||
if ( ipv6 != null && ipv6.equalsIgnoreCase( "enabled"))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Use the IPv6 bind all address
|
||||
|
||||
cifsConfig.setSMBBindAddress( InetAddress.getByName( "::"));
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isInfoEnabled())
|
||||
logger.info("Enabled CIFS IPv6 bind address for native SMB");
|
||||
}
|
||||
catch ( UnknownHostException ex)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to enable IPv6 bind address, " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1428,7 +1469,21 @@ public class ServerConfigurationBean extends ServerConfiguration implements Appl
|
||||
elem = config.getConfigElement("Win32Announce");
|
||||
if (elem != null)
|
||||
{
|
||||
// Check if the Win32 host announcer has been disabled
|
||||
|
||||
String enabled = elem.getAttribute("enabled");
|
||||
if ( enabled != null && enabled.equalsIgnoreCase( "false"))
|
||||
{
|
||||
// Switch off the Win32 host announcer
|
||||
|
||||
cifsConfig.setWin32HostAnnouncer( false);
|
||||
|
||||
// Log that host announcements are not enabled
|
||||
|
||||
logger.info("Win32 host announcements not enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for an announcement interval
|
||||
|
||||
String interval = elem.getAttribute("interval");
|
||||
@@ -1454,6 +1509,7 @@ public class ServerConfigurationBean extends ServerConfiguration implements Appl
|
||||
|
||||
cifsConfig.setWin32HostAnnouncer(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if NetBIOS and/or TCP/IP SMB have been enabled
|
||||
|
||||
@@ -1626,6 +1682,35 @@ public class ServerConfigurationBean extends ServerConfiguration implements Appl
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("NIO based code disabled for CIFS server");
|
||||
}
|
||||
|
||||
// Check if a session timeout is configured
|
||||
|
||||
elem = config.getConfigElement("sessionTimeout");
|
||||
if ( elem != null) {
|
||||
|
||||
// Validate the session timeout value
|
||||
|
||||
String sessTmo = elem.getValue();
|
||||
if ( sessTmo != null && sessTmo.length() > 0) {
|
||||
try {
|
||||
|
||||
// Convert the timeout value to milliseconds
|
||||
|
||||
int tmo = Integer.parseInt(sessTmo);
|
||||
if ( tmo < 0 || tmo > MaxSessionTimeout)
|
||||
throw new AlfrescoRuntimeException("Session timeout out of range (0 - " + MaxSessionTimeout + ")");
|
||||
|
||||
// Convert the session timeout to milliseconds
|
||||
|
||||
cifsConfig.setSocketTimeout( tmo * 1000);
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new AlfrescoRuntimeException("Invalid session timeout value, " + sessTmo);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new AlfrescoRuntimeException("Session timeout value not specified");
|
||||
}
|
||||
}
|
||||
catch ( InvalidConfigurationException ex)
|
||||
{
|
||||
@@ -3044,7 +3129,7 @@ public class ServerConfigurationBean extends ServerConfiguration implements Appl
|
||||
|
||||
String domainName = null;
|
||||
|
||||
if (getPlatformType() == Platform.Type.WINDOWS && isNativeCodeDisabled())
|
||||
if (getPlatformType() == Platform.Type.WINDOWS && isNativeCodeDisabled() == false)
|
||||
{
|
||||
// Get the local domain/workgroup name via JNI
|
||||
|
||||
|
@@ -398,7 +398,7 @@ public class AlfrescoCifsAuthenticator extends CifsAuthenticatorBase
|
||||
// Logging
|
||||
|
||||
if ( logger.isInfoEnabled())
|
||||
logger.info( "Logged on user " + client.getUserName() + " (" + sess.getRemoteAddress() + ") using auto-logon shared password");
|
||||
logger.info( "Logged on user " + client.getUserName() + " (" + sess.getRemoteAddress() + ")");
|
||||
|
||||
// Set the current user to be authenticated, save the authentication token
|
||||
|
||||
|
@@ -92,6 +92,9 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
|
||||
public final static int MinSessionTmo = 2000; // 2 seconds
|
||||
public final static int MaxSessionTmo = 30000; // 30 seconds
|
||||
|
||||
public final static int MinCheckInterval = 10; // 10 seconds
|
||||
public final static int MaxCheckInterval = 15 * 60; // 15 minutes
|
||||
|
||||
// Passthru keep alive interval
|
||||
|
||||
public final static long PassthruKeepAliveInterval = 60000L; // 60 seconds
|
||||
@@ -1155,9 +1158,42 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
|
||||
|
||||
super.initialize(config, params);
|
||||
|
||||
// Create the passthru authentication server list
|
||||
// Check if the offline check interval has been specified
|
||||
|
||||
ConfigElement checkInterval = params.getChild("offlineCheckInterval");
|
||||
if ( checkInterval != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Validate the check interval value
|
||||
|
||||
int offlineCheck = Integer.parseInt(checkInterval.getValue());
|
||||
|
||||
// Range check the value
|
||||
|
||||
if ( offlineCheck < MinCheckInterval || offlineCheck > MaxCheckInterval)
|
||||
throw new InvalidConfigurationException("Invalid offline check interval, valid range is " + MinCheckInterval + " to " + MaxCheckInterval);
|
||||
|
||||
// Set the offline check interval for offline passthru servers
|
||||
|
||||
m_passthruServers = new PassthruServers( offlineCheck);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Using offline check interval of " + offlineCheck + " seconds");
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
throw new InvalidConfigurationException("Invalid offline check interval specified");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the passthru server list with the default offline check interval
|
||||
|
||||
m_passthruServers = new PassthruServers();
|
||||
}
|
||||
|
||||
// Propagate the debug setting
|
||||
|
||||
|
@@ -36,10 +36,8 @@ import net.sf.acegisecurity.Authentication;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.filesys.AlfrescoConfigSection;
|
||||
import org.alfresco.filesys.ServerConfigurationBean;
|
||||
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
|
||||
import org.alfresco.jlan.ftp.FTPAuthenticator;
|
||||
import org.alfresco.jlan.ftp.FTPSrvSession;
|
||||
import org.alfresco.jlan.server.SrvSession;
|
||||
import org.alfresco.jlan.server.auth.ClientInfo;
|
||||
@@ -53,11 +51,6 @@ import org.alfresco.jlan.server.config.SecurityConfigSection;
|
||||
import org.alfresco.jlan.server.config.ServerConfiguration;
|
||||
import org.alfresco.jlan.smb.Protocol;
|
||||
import org.alfresco.jlan.util.IPAddress;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Passthru FTP Authenticator Class
|
||||
@@ -72,6 +65,9 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
|
||||
public final static int MinSessionTmo = 2000; // 2 seconds
|
||||
public final static int MaxSessionTmo = 30000; // 30 seconds
|
||||
|
||||
public final static int MinCheckInterval = 10; // 10 seconds
|
||||
public final static int MaxCheckInterval = 15 * 60; // 15 minutes
|
||||
|
||||
// Passthru keep alive interval
|
||||
|
||||
public final static long PassthruKeepAliveInterval = 60000L; // 60 seconds
|
||||
@@ -108,9 +104,42 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
|
||||
|
||||
m_passwordEncryptor = new PasswordEncryptor();
|
||||
|
||||
// Create the passthru authentication server list
|
||||
// Check if the offline check interval has been specified
|
||||
|
||||
ConfigElement checkInterval = params.getChild("offlineCheckInterval");
|
||||
if ( checkInterval != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Validate the check interval value
|
||||
|
||||
int offlineCheck = Integer.parseInt(checkInterval.getValue());
|
||||
|
||||
// Range check the value
|
||||
|
||||
if ( offlineCheck < MinCheckInterval || offlineCheck > MaxCheckInterval)
|
||||
throw new InvalidConfigurationException("Invalid offline check interval, valid range is " + MinCheckInterval + " to " + MaxCheckInterval);
|
||||
|
||||
// Set the offline check interval for offline passthru servers
|
||||
|
||||
m_passthruServers = new PassthruServers( offlineCheck);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Using offline check interval of " + offlineCheck + " seconds");
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
throw new InvalidConfigurationException("Invalid offline check interval specified");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the passthru server list with the default offline check interval
|
||||
|
||||
m_passthruServers = new PassthruServers();
|
||||
}
|
||||
|
||||
// Check if the session timeout has been specified
|
||||
|
||||
|
@@ -67,10 +67,12 @@ import org.alfresco.jlan.smb.server.SMBServer;
|
||||
import org.alfresco.jlan.smb.server.SMBSrvSession;
|
||||
import org.alfresco.jlan.util.WildCard;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.node.archive.NodeArchiveService;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationContext;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.lock.NodeLockedException;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -117,8 +119,9 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
private MimetypeService mimetypeService;
|
||||
private PermissionService permissionService;
|
||||
private FileFolderService fileFolderService;
|
||||
private NodeArchiveService nodeArchiveService;
|
||||
|
||||
private AuthenticationContext authenticationContext;
|
||||
private AuthenticationContext authContext;
|
||||
private AuthenticationService authService;
|
||||
|
||||
// Node monitor factory
|
||||
@@ -160,12 +163,12 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the authentication component
|
||||
* Return the authentication context
|
||||
*
|
||||
* @return AuthenticationContext
|
||||
*/
|
||||
public final AuthenticationContext getAuthenticationContext() {
|
||||
return authenticationContext;
|
||||
return authContext;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,6 +228,15 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
return this.permissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the node archive service
|
||||
*
|
||||
* @param NodeArchiveService
|
||||
*/
|
||||
public final NodeArchiveService getNodeArchiveService() {
|
||||
return nodeArchiveService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contentService the content service
|
||||
*/
|
||||
@@ -268,13 +280,13 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authentication component
|
||||
* Set the authentication context
|
||||
*
|
||||
* @param authComponent AuthenticationContext
|
||||
* @param authContext AuthenticationContext
|
||||
*/
|
||||
public void setAuthenticationContext(AuthenticationContext authComponent)
|
||||
public void setAuthenticationContext(AuthenticationContext authContext)
|
||||
{
|
||||
this.authenticationContext = authComponent;
|
||||
this.authContext = authContext;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,6 +326,15 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
m_nodeMonitorFactory = nodeMonitorFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the node archive service
|
||||
*
|
||||
* @param NodeArchiveService nodeArchiveService
|
||||
*/
|
||||
public void setNodeArchiveService(NodeArchiveService nodeArchiveService) {
|
||||
this.nodeArchiveService = nodeArchiveService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -1418,6 +1439,11 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
// Store the state with the file
|
||||
|
||||
netFile.setFileState( fstate);
|
||||
|
||||
// Set the file access date/time, if available
|
||||
|
||||
if ( fstate.hasAccessDateTime())
|
||||
netFile.setAccessDate( fstate.getAccessDateTime());
|
||||
}
|
||||
|
||||
// If the file has been opened for overwrite then truncate the file to zero length, this will
|
||||
@@ -1857,15 +1883,23 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
|
||||
fileFolderService.delete(nodeRef);
|
||||
|
||||
// Remove the file state
|
||||
// Set the file state to indicate a delete on close
|
||||
|
||||
if ( ctx.hasStateTable())
|
||||
ctx.getStateTable().removeFileState(file.getFullName());
|
||||
{
|
||||
// Get, or create, the file state
|
||||
|
||||
// Commit the current transaction
|
||||
FileState fState = ctx.getStateTable().findFileState(file.getFullName(), false, true);
|
||||
|
||||
// sess.endTransaction();
|
||||
// beginReadTransaction( sess);
|
||||
// Indicate that the file was deleted via a delete on close request
|
||||
|
||||
fState.setFileStatus(FileStateStatus.DeleteOnClose);
|
||||
|
||||
// Make sure the file state is cached for a short while, save the noderef details
|
||||
|
||||
fState.setExpiryTime(System.currentTimeMillis() + FileState.RenameTimeout);
|
||||
fState.setNodeRef(nodeRef);
|
||||
}
|
||||
}
|
||||
catch (org.alfresco.repo.security.permissions.AccessDeniedException ex)
|
||||
{
|
||||
@@ -1939,11 +1973,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Deleted file: \n" +
|
||||
" file: " + name + "\n" +
|
||||
" node: " + nodeRef);
|
||||
}
|
||||
logger.debug("Deleted file: " + name + ", node: " + nodeRef);
|
||||
}
|
||||
catch (NodeLockedException ex)
|
||||
{
|
||||
@@ -2033,11 +2063,15 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
|
||||
if ( !cifsHelper.isDirectory(nodeToMoveRef) )
|
||||
{
|
||||
// Check if there is a renamed file state for the new file name
|
||||
// Check if there is a renamed or delete on close file state for the new file name
|
||||
|
||||
FileState renState = ctx.getStateTable().removeFileState(newName);
|
||||
|
||||
if ( renState != null && renState.getFileStatus() == FileStateStatus.Renamed)
|
||||
if ( renState != null)
|
||||
{
|
||||
// Check if there is a renamed state for the new file
|
||||
|
||||
if ( renState.getFileStatus() == FileStateStatus.Renamed)
|
||||
{
|
||||
// DEBUG
|
||||
|
||||
@@ -2066,6 +2100,78 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
|
||||
fstate.setNodeRef(renState.getNodeRef());
|
||||
fstate.setFileStatus(FileStateStatus.FileExists);
|
||||
}
|
||||
else if ( renState.getFileStatus() == FileStateStatus.DeleteOnClose)
|
||||
{
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug(" Found delete on close state, restore and relink, " + renState);
|
||||
|
||||
// Restore the deleted node so we can relink the new version to the old history/properties
|
||||
|
||||
NodeRef archivedNode = getNodeArchiveService().getArchivedNode( renState.getNodeRef());
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug(" Found archived node + " + archivedNode);
|
||||
|
||||
if ( archivedNode != null && getNodeService().exists( archivedNode))
|
||||
{
|
||||
// Restore the node
|
||||
|
||||
NodeRef restoredNode = getNodeService().restoreNode( archivedNode, null, null, null);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug(" Restored node " + restoredNode);
|
||||
|
||||
if ( restoredNode != null)
|
||||
{
|
||||
// Get the properties for the old and new nodes
|
||||
|
||||
org.alfresco.service.cmr.model.FileInfo restoredFileInfo = fileFolderService.getFileInfo(restoredNode);
|
||||
org.alfresco.service.cmr.model.FileInfo fileToMoveInfo = fileFolderService.getFileInfo(nodeToMoveRef);
|
||||
|
||||
// Swap the content between the temp and restored file
|
||||
|
||||
ContentData oldContentData = restoredFileInfo.getContentData();
|
||||
ContentData newContentData = fileToMoveInfo.getContentData();
|
||||
|
||||
nodeService.setProperty(restoredNode, ContentModel.PROP_CONTENT, newContentData);
|
||||
nodeService.setProperty(nodeToMoveRef, ContentModel.PROP_CONTENT, oldContentData);
|
||||
|
||||
relinked = true;
|
||||
|
||||
// Delete the node that was being renamed
|
||||
|
||||
nodeService.deleteNode(nodeToMoveRef);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug(" Swapped content to restored node, delete " + oldName + ", nodeRef=" + nodeToMoveRef);
|
||||
|
||||
// Link the node ref for the associated rename state
|
||||
|
||||
if ( renState.hasRenameState())
|
||||
renState.getRenameState().setNodeRef(nodeToMoveRef);
|
||||
|
||||
// Remove the file state for the old file name
|
||||
|
||||
ctx.getStateTable().removeFileState(oldName);
|
||||
|
||||
// Get, or create, a file state for the new file path
|
||||
|
||||
FileState fstate = ctx.getStateTable().findFileState(newName, false, true);
|
||||
|
||||
fstate.setNodeRef(restoredNode);
|
||||
fstate.setFileStatus(FileStateStatus.FileExists);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -57,7 +57,7 @@ public class FileState
|
||||
|
||||
// File status
|
||||
|
||||
public enum FileStateStatus { NotExist, FileExists, FolderExists, Renamed };
|
||||
public enum FileStateStatus { NotExist, FileExists, FolderExists, Renamed, DeleteOnClose };
|
||||
|
||||
// File name/path
|
||||
|
||||
|
@@ -32,6 +32,7 @@ import org.alfresco.jlan.locking.NotLockedException;
|
||||
import org.alfresco.jlan.server.SrvSession;
|
||||
import org.alfresco.jlan.server.filesys.NetworkFile;
|
||||
import org.alfresco.jlan.server.filesys.TreeConnection;
|
||||
import org.alfresco.jlan.server.filesys.pseudo.MemoryNetworkFile;
|
||||
import org.alfresco.jlan.server.locking.LockManager;
|
||||
import org.alfresco.filesys.alfresco.AlfrescoNetworkFile;
|
||||
|
||||
@@ -65,6 +66,10 @@ public class FileStateLockManager implements LockManager {
|
||||
AlfrescoNetworkFile alfFile = (AlfrescoNetworkFile) file;
|
||||
fstate = alfFile.getFileState();
|
||||
}
|
||||
else if ( file instanceof MemoryNetworkFile) {
|
||||
file.addLock(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( fstate == null)
|
||||
throw new IOException("Open file without state (lock)");
|
||||
@@ -98,6 +103,10 @@ public class FileStateLockManager implements LockManager {
|
||||
AlfrescoNetworkFile alfFile = (AlfrescoNetworkFile) file;
|
||||
fstate = alfFile.getFileState();
|
||||
}
|
||||
else if ( file instanceof MemoryNetworkFile) {
|
||||
file.removeLock(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( fstate == null)
|
||||
throw new IOException("Open file without state (unlock)");
|
||||
|
Reference in New Issue
Block a user