diff --git a/source/java/org/alfresco/filesys/repo/ContentContext.java b/source/java/org/alfresco/filesys/repo/ContentContext.java index 37943dcb43..a9049c9ba9 100644 --- a/source/java/org/alfresco/filesys/repo/ContentContext.java +++ b/source/java/org/alfresco/filesys/repo/ContentContext.java @@ -26,8 +26,11 @@ package org.alfresco.filesys.repo; import org.alfresco.filesys.alfresco.AlfrescoContext; import org.alfresco.filesys.alfresco.IOControlHandler; +import org.alfresco.jlan.server.core.DeviceContextException; import org.alfresco.jlan.server.filesys.DiskInterface; +import org.alfresco.jlan.server.filesys.DiskSharedDevice; import org.alfresco.jlan.server.filesys.FileSystem; +import org.alfresco.jlan.smb.server.notify.NotifyChangeHandler; import org.alfresco.service.cmr.repository.*; /** @@ -48,6 +51,10 @@ public class ContentContext extends AlfrescoContext private NodeRef m_rootNodeRef; + // Node monitor + + private NodeMonitor m_nodeMonitor; + /** * Class constructor * @@ -114,6 +121,11 @@ public class ContentContext extends AlfrescoContext * Close the filesystem context */ public void CloseContext() { + + // Stop the node monitor, if enabled + + if ( m_nodeMonitor != null) + m_nodeMonitor.shutdownRequest(); // Call the base class @@ -130,4 +142,32 @@ public class ContentContext extends AlfrescoContext { return new ContentIOControlHandler(); } + + /** + * Create the node monitor + * + * @param filesysDriver ContentDiskDriver + */ + protected void createNodeMonitor( ContentDiskDriver filesysDriver) { + m_nodeMonitor = new NodeMonitor( filesysDriver, this); + } + + /** + * Start the filesystem + * + * @param share DiskSharedDevice + * @exception DeviceContextException + */ + public void startFilesystem(DiskSharedDevice share) + throws DeviceContextException { + + // Call the base class + + super.startFilesystem(share); + + // Start the node monitor, if enabled + + if ( m_nodeMonitor != null) + m_nodeMonitor.startMonitor(); + } } diff --git a/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java b/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java index 53b3e24711..8067e6aa13 100644 --- a/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java +++ b/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java @@ -67,6 +67,7 @@ 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.policy.PolicyComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.service.cmr.lock.NodeLockedException; import org.alfresco.service.cmr.model.FileFolderService; @@ -120,6 +121,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa private AuthenticationComponent authComponent; private AuthenticationService authService; + private PolicyComponent policyComponent; + // Lock manager private static LockManager _lockManager = new FileStateLockManager(); @@ -153,6 +156,15 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa { return authService; } + + /** + * Return the authentication component + * + * @return AuthenticationComponent + */ + public final AuthenticationComponent getAuthComponent() { + return authComponent; + } /** * Return the node service @@ -193,6 +205,33 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa return this.searchService; } + /** + * Return the file folder service + * + * @return FileFolderService + */ + public final FileFolderService getFileFolderService() { + return this.fileFolderService; + } + + /** + * Return the permission service + * + * @return PermissionService + */ + public final PermissionService getPermissionService() { + return this.permissionService; + } + + /** + * Return the policy component + * + * @return PolicyComponent + */ + public final PolicyComponent getPolicyComponent() { + return this.policyComponent; + } + /** * @param contentService the content service */ @@ -273,6 +312,15 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa this.mimetypeService = mimetypeService; } + /** + * Set the policy component + * + * @param policyComponent PolicyComponent + */ + public void setPolicyComponent(PolicyComponent policyComponent) { + this.policyComponent = policyComponent; + } + /** * 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 @@ -498,6 +546,15 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa if ( context.hasIOHandler()) context.getIOHandler().initialize( this, context); + // Install the node service monitor + + if ( cfg.getChild("disableNodeMonitor") == null) { + + // Create the node monitor + + context.createNodeMonitor( this); + } + // Return the context for this shared filesystem return context; diff --git a/source/java/org/alfresco/filesys/repo/CreateNodeEvent.java b/source/java/org/alfresco/filesys/repo/CreateNodeEvent.java new file mode 100644 index 0000000000..e08a401f72 --- /dev/null +++ b/source/java/org/alfresco/filesys/repo/CreateNodeEvent.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006-2008 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.filesys.repo; + +import org.alfresco.service.cmr.model.FileFolderServiceType; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Create Node Event Class + * + * @author gkspencer + */ +public class CreateNodeEvent extends NodeEvent { + + /** + * Class constructor + * + * @param fType FileFolderServiceTtype + * @param nodeRef NodeRef + */ + public CreateNodeEvent( FileFolderServiceType fType, NodeRef nodeRef) { + super( fType, nodeRef); + } + + /** + * Return the node event as a string + * + * @return String + */ + public String toString() { + StringBuilder str = new StringBuilder(); + + str.append("[Create:fType="); + str.append(getFileType()); + str.append(",nodeRef="); + str.append(getNodeRef()); + str.append("]"); + + return str.toString(); + } +} diff --git a/source/java/org/alfresco/filesys/repo/DeleteNodeEvent.java b/source/java/org/alfresco/filesys/repo/DeleteNodeEvent.java new file mode 100644 index 0000000000..c366203076 --- /dev/null +++ b/source/java/org/alfresco/filesys/repo/DeleteNodeEvent.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2006-2008 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.filesys.repo; + +import org.alfresco.service.cmr.model.FileFolderServiceType; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Delete Node Event Class + * + * @author gkspencer + */ +public class DeleteNodeEvent extends NodeEvent { + + // Deleted node path and confirmation + + private String m_path; + + private boolean m_deleteConfirm; + + /** + * Class constructor + * + * @param fType FileFolderServiceTtype + * @param nodeRef NodeRef + * @param path String + */ + public DeleteNodeEvent( FileFolderServiceType fType, NodeRef nodeRef, String path) { + super( fType, nodeRef); + + m_path = path; + } + + /** + * Return the relative path of the target node + * + * @return String + */ + public final String getPath() { + return m_path; + } + + /** + * Check if the delete confirm flag is set + * + * @return boolean + */ + public final boolean hasDeleteConfirm() { + return m_deleteConfirm; + } + + /** + * Set/clear the delete confirm flag + * + * @param delConfirm boolean + */ + public final void setDeleteConfirm( boolean delConfirm) { + m_deleteConfirm = delConfirm; + } + + /** + * Return the node event as a string + * + * @return String + */ + public String toString() { + StringBuilder str = new StringBuilder(); + + str.append("[Delete:fType="); + str.append(getFileType()); + str.append(",nodeRef="); + str.append(getNodeRef()); + str.append(",path="); + str.append(getPath()); + str.append(",confirm="); + str.append(hasDeleteConfirm()); + str.append("]"); + + return str.toString(); + } +} diff --git a/source/java/org/alfresco/filesys/repo/LockNodeEvent.java b/source/java/org/alfresco/filesys/repo/LockNodeEvent.java new file mode 100644 index 0000000000..015444c374 --- /dev/null +++ b/source/java/org/alfresco/filesys/repo/LockNodeEvent.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2006-2008 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.filesys.repo; + +import org.alfresco.service.cmr.model.FileFolderServiceType; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Lock Node Event Class + * + * @author gkspencer + */ +public class LockNodeEvent extends NodeEvent { + + // Before and after lock types + + private String m_lockBefore; + private String m_lockAfter; + + /** + * Class constructor + * + * @param fType FileFolderServiceTtype + * @param nodeRef NodeRef + * @param lockBefore String + * @param lockAfter String + */ + public LockNodeEvent( FileFolderServiceType fType, NodeRef nodeRef, String lockBefore, String lockAfter) { + super( fType, nodeRef); + + m_lockAfter = lockAfter; + m_lockBefore = lockBefore; + } + + /** + * Return the previous type + * + * @return String + */ + public final String getBeforeLockType() { + return m_lockBefore; + } + + /** + * Return the new lock type + * + * @return String + */ + public final String getAfterLockType() { + return m_lockAfter; + } + + /** + * Return the node event as a string + * + * @return String + */ + public String toString() { + StringBuilder str = new StringBuilder(); + + str.append("[Lock:fType="); + str.append(getFileType()); + str.append(",nodeRef="); + str.append(getNodeRef()); + str.append(",lockBefore="); + str.append(getBeforeLockType()); + str.append(",lockAfter="); + str.append(getAfterLockType()); + str.append("]"); + + return str.toString(); + } +} diff --git a/source/java/org/alfresco/filesys/repo/MoveNodeEvent.java b/source/java/org/alfresco/filesys/repo/MoveNodeEvent.java new file mode 100644 index 0000000000..9713942389 --- /dev/null +++ b/source/java/org/alfresco/filesys/repo/MoveNodeEvent.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2006-2008 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.filesys.repo; + +import org.alfresco.service.cmr.model.FileFolderServiceType; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Move Node Event Class + * + * @author gkspencer + */ +public class MoveNodeEvent extends NodeEvent { + + // Moved node path and destination node + + private String m_path; + + private NodeRef m_moveToNode; + + /** + * Class constructor + * + * @param fType FileFolderServiceTtype + * @param nodeRef NodeRef + * @param fromPath String + * @param toNodeRef NodeRef + */ + public MoveNodeEvent( FileFolderServiceType fType, NodeRef nodeRef, String fromPath, NodeRef toNodeRef) { + super( fType, nodeRef); + + m_path = fromPath; + m_moveToNode = toNodeRef; + } + + /** + * Return the relative path of the target node + * + * @return String + */ + public final String getPath() { + return m_path; + } + + /** + * Return the target node for a move + * + * @return NodeRef + */ + public final NodeRef getMoveToNodeRef() { + return m_moveToNode; + } + + /** + * Return the node event as a string + * + * @return String + */ + public String toString() { + StringBuilder str = new StringBuilder(); + + str.append("[Move:fType="); + str.append(getFileType()); + str.append(",nodeRef="); + str.append(getNodeRef()); + str.append(",path="); + str.append(getPath()); + str.append(",toNodeRef="); + str.append(getMoveToNodeRef()); + str.append("]"); + + return str.toString(); + } +} diff --git a/source/java/org/alfresco/filesys/repo/NodeEvent.java b/source/java/org/alfresco/filesys/repo/NodeEvent.java new file mode 100644 index 0000000000..524ba5c2ef --- /dev/null +++ b/source/java/org/alfresco/filesys/repo/NodeEvent.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2006-2008 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.filesys.repo; + +import org.alfresco.service.cmr.model.FileFolderServiceType; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Node Event Base Class + * + *
Contains the details of a file/folder node event to be processed by a node monitor thread.
+ *
+ * @author gkspencer
+ */
+public class NodeEvent {
+
+ // Target node
+
+ private NodeRef m_nodeRef;
+
+ // File/folder node type
+
+ private FileFolderServiceType m_fileType;
+
+ /**
+ * Class constructor
+ *
+ * @param fType FileFolderServiceTtype
+ * @param nodeRef NodeRef
+ */
+ protected NodeEvent( FileFolderServiceType fType, NodeRef nodeRef) {
+ m_fileType = fType;
+ m_nodeRef = nodeRef;
+ }
+
+ /**
+ * Return the target node
+ *
+ * @return NodeRef
+ */
+ public final NodeRef getNodeRef() {
+ return m_nodeRef;
+ }
+
+ /**
+ * Return the node file/folder type
+ *
+ * @return FileFolderServiceType
+ */
+ public final FileFolderServiceType getFileType() {
+ return m_fileType;
+ }
+
+}
diff --git a/source/java/org/alfresco/filesys/repo/NodeEventQueue.java b/source/java/org/alfresco/filesys/repo/NodeEventQueue.java
new file mode 100644
index 0000000000..800a91e230
--- /dev/null
+++ b/source/java/org/alfresco/filesys/repo/NodeEventQueue.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2006-2008 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of
+ * the GPL, you may redistribute this Program in connection with Free/Libre
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's
+ * FLOSS exception. You should have recieved a copy of the text describing
+ * the FLOSS exception, and it is also available here:
+ * http://www.alfresco.com/legal/licensing"
+ */
+
+package org.alfresco.filesys.repo;
+
+import java.util.LinkedList;
+
+/**
+ * Node Event Queue Class
+ *
+ * @author gkspencer
+ */
+public class NodeEventQueue {
+
+ // List of node events
+
+ private LinkedList Monitor node events from the node service to update the file state cache and feed notification events into
+ * the file server change notification handler.
+ *
+ * @author gkspencer
+ */
+public class NodeMonitor extends TransactionListenerAdapter
+ implements NodeServicePolicies.OnCreateNodePolicy,
+ NodeServicePolicies.OnUpdatePropertiesPolicy,
+ NodeServicePolicies.BeforeDeleteNodePolicy,
+ NodeServicePolicies.OnMoveNodePolicy,
+ Runnable
+{
+ // Logging
+
+ private static final Log logger = LogFactory.getLog(NodeMonitor.class);
+
+ // Transaction object binding keys
+
+ public static final String FileSysNodeEvent = "FileSysNodeEvent";
+ public static final String FileSysNodeEvent2 = "FileSysNodeEvent2";
+
+ // Services/components
+
+ private PolicyComponent m_policyComponent;
+ private NodeService m_nodeService;
+ private FileFolderService m_fileFolderService;
+ private PermissionService m_permissionService;
+ private TransactionService m_transService;
+
+ // Filesystem driver and context
+
+ private ContentDiskDriver m_filesysDriver;
+ private ContentContext m_filesysCtx;
+
+ // File state table and change notification handler
+
+ private FileStateTable m_stateTable;
+ private NotifyChangeHandler m_changeHandler;
+
+ // Root node path and store
+
+ private String m_rootPath;
+ private StoreRef m_storeRef;
+
+ // Queue of node update events
+
+ private NodeEventQueue m_eventQueue;
+
+ // Thread for the main event processing
+
+ private Thread m_thread;
+ private boolean m_shutdown;
+
+ /**
+ * Class constructor
+ *
+ * @param filesysDriver ContentDiskDriver
+ * @param filesysCtx ContentContext
+ */
+ public NodeMonitor( ContentDiskDriver filesysDriver, ContentContext filesysCtx) {
+ m_filesysDriver = filesysDriver;
+ m_filesysCtx = filesysCtx;
+
+ // Initialize the node monitor
+
+ init();
+ }
+
+ /**
+ * Initialize the node monitor
+ */
+ public final void init() {
+
+ // Get various services via the filesystem driver
+
+ m_nodeService = m_filesysDriver.getNodeService();
+ m_policyComponent = m_filesysDriver.getPolicyComponent();
+ m_fileFolderService = m_filesysDriver.getFileFolderService();
+ m_permissionService = m_filesysDriver.getPermissionService();
+ m_transService = m_filesysDriver.getTransactionService();
+
+ // Disable change notifications from the file server
+
+ m_filesysCtx.setFileServerNotifications( false);
+
+ // Register for node service events
+
+ m_policyComponent.bindClassBehaviour( QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
+ this, new JavaBehaviour(this, "onCreateNode"));
+ m_policyComponent.bindClassBehaviour( QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
+ this, new JavaBehaviour(this, "beforeDeleteNode"));
+ m_policyComponent.bindClassBehaviour( QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"),
+ this, new JavaBehaviour(this, "onDeleteNode"));
+ m_policyComponent.bindClassBehaviour( QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"),
+ this, new JavaBehaviour(this, "onMoveNode"));
+ m_policyComponent.bindClassBehaviour( QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
+ this, new JavaBehaviour(this, "onUpdateProperties"));
+
+ // Get the store
+
+ m_storeRef = m_filesysCtx.getRootNode().getStoreRef();
+
+ // Get the root node path
+
+ String rootPath = (String) m_nodeService.getProperty( m_filesysCtx.getRootNode(), ContentModel.PROP_NAME);
+
+ StringBuilder pathBuilder= new StringBuilder();
+ pathBuilder.append("/");
+ if ( rootPath != null && rootPath.length() > 0)
+ pathBuilder.append( rootPath);
+
+ m_rootPath = pathBuilder.toString();
+
+ // DEBUG
+
+ if ( logger.isDebugEnabled())
+ logger.debug("Node monitor filesystem=" + m_filesysCtx.getDeviceName() + ", rootPath=" + m_rootPath);
+
+ // Create the node event queue
+
+ m_eventQueue = new NodeEventQueue();
+
+ // DEBUG
+
+ if ( logger.isDebugEnabled())
+ logger.debug("Node monitor installed for " + m_filesysCtx.getDeviceName());
+ }
+
+ /**
+ * Start the node monitor thread
+ */
+ public void startMonitor() {
+
+ // Get the file state table and change notification handler, if enabled
+
+ m_stateTable = m_filesysCtx.getStateTable();
+ m_changeHandler = m_filesysCtx.getChangeHandler();
+
+ // Start the event processing thread
+
+ m_thread = new Thread( this);
+ m_thread.setName( "NodeMonitor_" + m_filesysCtx.getDeviceName());
+ m_thread.setDaemon( true);
+
+ m_thread.start();
+
+ // DEBUG
+
+ if ( logger.isDebugEnabled())
+ logger.debug("NodeMonitor started, " + m_thread.getName());
+ }
+
+ /**
+ * Create node event
+ *
+ * @param childAssocRef ChildAssociationRef
+ */
+ public void onCreateNode(ChildAssociationRef childAssocRef) {
+
+ // Check if the node is a file/folder
+
+ NodeRef nodeRef = childAssocRef.getChildRef();
+ if ( nodeRef.getStoreRef().equals( m_storeRef) == false)
+ return;
+
+ QName nodeType = m_nodeService.getType( nodeRef);
+ FileFolderServiceType fType = m_fileFolderService.getType( nodeType);
+
+ if ( fType != FileFolderServiceType.INVALID) {
+
+ // DEBUG
+
+ if ( logger.isDebugEnabled()) {
+
+ // Get the full path to the file/folder node
+
+ Path nodePath = m_nodeService.getPath( nodeRef);
+ String fName = (String) m_nodeService.getProperty( nodeRef, ContentModel.PROP_NAME);
+
+ logger.debug("OnCreateNode: nodeRef=" + nodeRef + ", name=" + fName + ", path=" + nodePath.toDisplayPath(m_nodeService, m_permissionService));
+ }
+
+ // Create an event to process the node creation
+
+ NodeEvent nodeEvent = new CreateNodeEvent( fType, nodeRef);
+
+ // Store the event in the transaction until committed, and register the transaction listener
+
+ AlfrescoTransactionSupport.bindListener( this);
+ AlfrescoTransactionSupport.bindResource( FileSysNodeEvent, nodeEvent);
+ }
+ }
+
+ /**
+ * Update properties event
+ *
+ * @param nodeRef NodeRef
+ * @param before Map