ALF-10200 - NodeMonitor: StringIndexOutOfBoundsException

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30471 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2011-09-13 13:01:40 +00:00
parent 271595f862
commit ca11ba7b54
4 changed files with 156 additions and 122 deletions

View File

@@ -29,14 +29,19 @@ import org.alfresco.service.cmr.repository.NodeRef;
*/ */
public class CreateNodeEvent extends NodeEvent { public class CreateNodeEvent extends NodeEvent {
private String relPath;
private String name;
/** /**
* Class constructor * Class constructor
* *
* @param fType FileFolderServiceTtype * @param fType FileFolderServiceTtype
* @param nodeRef NodeRef * @param nodeRef NodeRef
*/ */
public CreateNodeEvent( FileFolderServiceType fType, NodeRef nodeRef) { public CreateNodeEvent( FileFolderServiceType fType, NodeRef nodeRef, String relPath, String name) {
super( fType, nodeRef); super( fType, nodeRef);
this.setRelPath(relPath);
this.setName(name);
} }
/** /**
@@ -55,4 +60,24 @@ public class CreateNodeEvent extends NodeEvent {
return str.toString(); return str.toString();
} }
public void setRelPath(String relPath)
{
this.relPath = relPath;
}
public String getRelPath()
{
return relPath;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
} }

View File

@@ -33,6 +33,9 @@ public class LockNodeEvent extends NodeEvent {
private String m_lockBefore; private String m_lockBefore;
private String m_lockAfter; private String m_lockAfter;
private String relPath;
private String name;
/** /**
* Class constructor * Class constructor
@@ -42,11 +45,13 @@ public class LockNodeEvent extends NodeEvent {
* @param lockBefore String * @param lockBefore String
* @param lockAfter String * @param lockAfter String
*/ */
public LockNodeEvent( FileFolderServiceType fType, NodeRef nodeRef, String lockBefore, String lockAfter) { public LockNodeEvent( FileFolderServiceType fType, NodeRef nodeRef, String relPath, String name, String lockBefore, String lockAfter) {
super( fType, nodeRef); super( fType, nodeRef);
m_lockAfter = lockAfter; m_lockAfter = lockAfter;
m_lockBefore = lockBefore; m_lockBefore = lockBefore;
this.setRelPath(relPath);
this.setName(name);
} }
/** /**
@@ -87,4 +92,24 @@ public class LockNodeEvent extends NodeEvent {
return str.toString(); return str.toString();
} }
public void setRelPath(String relPath)
{
this.relPath = relPath;
}
public String getRelPath()
{
return relPath;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
} }

View File

@@ -31,9 +31,8 @@ public class MoveNodeEvent extends NodeEvent {
// Moved node path and destination node // Moved node path and destination node
private String m_path; private String fromPath;
private String toPath;
private NodeRef m_moveToNode;
/** /**
* Class constructor * Class constructor
@@ -43,11 +42,11 @@ public class MoveNodeEvent extends NodeEvent {
* @param fromPath String * @param fromPath String
* @param toNodeRef NodeRef * @param toNodeRef NodeRef
*/ */
public MoveNodeEvent( FileFolderServiceType fType, NodeRef nodeRef, String fromPath, NodeRef toNodeRef) { public MoveNodeEvent( FileFolderServiceType fType, NodeRef nodeRef, String fromPath, String toPath) {
super( fType, nodeRef); super( fType, nodeRef);
m_path = fromPath; this.fromPath = fromPath;
m_moveToNode = toNodeRef; this.toPath = toPath;
} }
/** /**
@@ -55,19 +54,16 @@ public class MoveNodeEvent extends NodeEvent {
* *
* @return String * @return String
*/ */
public final String getPath() { public final String getFromPath()
return m_path; {
return fromPath;
} }
/** public final String getToPath()
* Return the target node for a move {
* return fromPath;
* @return NodeRef
*/
public final NodeRef getMoveToNodeRef() {
return m_moveToNode;
} }
/** /**
* Return the node event as a string * Return the node event as a string
* *
@@ -80,10 +76,10 @@ public class MoveNodeEvent extends NodeEvent {
str.append(getFileType()); str.append(getFileType());
str.append(",nodeRef="); str.append(",nodeRef=");
str.append(getNodeRef()); str.append(getNodeRef());
str.append(",path="); str.append(",fromPath=");
str.append(getPath()); str.append(getFromPath());
str.append(",toNodeRef="); str.append(",toPath=");
str.append(getMoveToNodeRef()); str.append(getToPath());
str.append("]"); str.append("]");
return str.toString(); return str.toString();

View File

@@ -48,6 +48,7 @@ import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -84,17 +85,14 @@ public class NodeMonitor extends TransactionListenerAdapter
private TransactionService m_transService; private TransactionService m_transService;
// Filesystem driver and context // Filesystem driver and context
// private ContentDiskDriver m_filesysDriver; // TODO needs to be configured with many filesystem contexts.
private ContentContext m_filesysCtx; private ContentContext m_filesysCtx;
// File state table and change notification handler // File state table
private FileStateCache m_stateTable; private FileStateCache m_stateTable;
private NotifyChangeHandler m_changeHandler;
// Root node path and store // Root node path and store
private String m_rootPath; private String m_rootPath;
private StoreRef m_storeRef; private StoreRef m_storeRef;
@@ -115,7 +113,6 @@ public class NodeMonitor extends TransactionListenerAdapter
*/ */
protected NodeMonitor(ContentContext filesysCtx, NodeService nodeService, PolicyComponent policyComponent, protected NodeMonitor(ContentContext filesysCtx, NodeService nodeService, PolicyComponent policyComponent,
FileFolderService fileFolderService, PermissionService permissionService, TransactionService transService) { FileFolderService fileFolderService, PermissionService permissionService, TransactionService transService) {
// m_filesysDriver = filesysDriver;
m_filesysCtx = filesysCtx; m_filesysCtx = filesysCtx;
// Set various services // Set various services
@@ -134,7 +131,14 @@ public class NodeMonitor extends TransactionListenerAdapter
/** /**
* Initialize the node monitor * Initialize the node monitor
*/ */
public final void init() { public final void init()
{
PropertyCheck.mandatory(this, "nodeService", m_nodeService);
PropertyCheck.mandatory(this, "filesysCtx", m_filesysCtx);
PropertyCheck.mandatory(this, "policyComponent", m_policyComponent);
PropertyCheck.mandatory(this, "fileFolderService", m_fileFolderService);
PropertyCheck.mandatory(this, "permissionService", m_permissionService);
PropertyCheck.mandatory(this, "transService", m_transService);
// Disable change notifications from the file server // Disable change notifications from the file server
@@ -189,9 +193,7 @@ public class NodeMonitor extends TransactionListenerAdapter
public void startMonitor() { public void startMonitor() {
// Get the file state table and change notification handler, if enabled // Get the file state table and change notification handler, if enabled
m_stateTable = m_filesysCtx.getStateCache(); m_stateTable = m_filesysCtx.getStateCache();
m_changeHandler = m_filesysCtx.getChangeHandler();
// Start the event processing thread // Start the event processing thread
@@ -218,28 +220,28 @@ public class NodeMonitor extends TransactionListenerAdapter
NodeRef nodeRef = childAssocRef.getChildRef(); NodeRef nodeRef = childAssocRef.getChildRef();
if ( nodeRef.getStoreRef().equals( m_storeRef) == false) if ( nodeRef.getStoreRef().equals( m_storeRef) == false)
{
// different store so irrelevant
return; return;
}
QName nodeType = m_nodeService.getType( nodeRef); QName nodeType = m_nodeService.getType( nodeRef);
FileFolderServiceType fType = m_fileFolderService.getType( nodeType); FileFolderServiceType fType = m_fileFolderService.getType( nodeType);
if ( fType != FileFolderServiceType.INVALID) { if ( fType != FileFolderServiceType.INVALID)
{
// DEBUG // Node is not INVALID - therefore its VALID
Path nodePath = m_nodeService.getPath( nodeRef);
if ( logger.isDebugEnabled()) { String relPath = nodePath.toDisplayPath(m_nodeService, m_permissionService);
String fName = (String) m_nodeService.getProperty( nodeRef, ContentModel.PROP_NAME);
// Get the full path to the file/folder node if ( logger.isDebugEnabled())
{
Path nodePath = m_nodeService.getPath( nodeRef); logger.debug("OnCreateNode: nodeRef=" + nodeRef + ", name=" + fName + ", path=" + relPath);
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 // Create an event to process the node creation
NodeEvent nodeEvent = new CreateNodeEvent( fType, nodeRef, relPath, fName);
NodeEvent nodeEvent = new CreateNodeEvent( fType, nodeRef);
// Store the event in the transaction until committed, and register the transaction listener // Store the event in the transaction until committed, and register the transaction listener
fireNodeEvent(nodeEvent); fireNodeEvent(nodeEvent);
@@ -258,34 +260,42 @@ public class NodeMonitor extends TransactionListenerAdapter
// Check that the node is in our store // Check that the node is in our store
if ( nodeRef.getStoreRef().equals( m_storeRef) == false) if ( nodeRef.getStoreRef().equals( m_storeRef) == false)
{
return; return;
}
// Check if the node is a file/folder // Check if the node is a file/folder
QName nodeType = m_nodeService.getType( nodeRef); QName nodeType = m_nodeService.getType( nodeRef);
FileFolderServiceType fType = m_fileFolderService.getType( nodeType); FileFolderServiceType fType = m_fileFolderService.getType( nodeType);
if ( fType != FileFolderServiceType.INVALID) { if ( fType != FileFolderServiceType.INVALID)
{
// Check if there has been a lock change // Check if there has been a lock change
String beforeLock = (String) before.get( ContentModel.PROP_LOCK_TYPE); String beforeLock = (String) before.get( ContentModel.PROP_LOCK_TYPE);
String afterLock = (String) after.get( ContentModel.PROP_LOCK_TYPE); String afterLock = (String) after.get( ContentModel.PROP_LOCK_TYPE);
String beforeName = (String) before.get(ContentModel.PROP_NAME);
String afterName = (String) after.get(ContentModel.PROP_NAME);
Path nodePath = m_nodeService.getPath(nodeRef);
String relPath = nodePath.toDisplayPath(m_nodeService, m_permissionService);
if (( beforeLock != null && afterLock == null) || if (( beforeLock != null && afterLock == null) ||
( beforeLock == null && afterLock != null)) { ( beforeLock == null && afterLock != null))
// Process the update {
fireNodeEvent(new LockNodeEvent( fType, nodeRef, beforeLock, afterLock)); // Process the lock update first
fireNodeEvent(new LockNodeEvent( fType, nodeRef, relPath, beforeName, beforeLock, afterLock));
} }
// Check if node has been renamed // Check if node has been renamed
String beforeName = (String) before.get(ContentModel.PROP_NAME); if (beforeName != null && !beforeName.equals(afterName))
String afterName = (String) after.get(ContentModel.PROP_NAME); {
// Yes Node has been renamed in the same folder
if (beforeName != null && !beforeName.equals(afterName)) {
ChildAssociationRef childAssocRef = m_nodeService.getPrimaryParent(nodeRef); ChildAssociationRef childAssocRef = m_nodeService.getPrimaryParent(nodeRef);
String relPath = buildRelativePathString(childAssocRef.getParentRef(), nodeRef, beforeName); String relPath2 = buildRelativePathString(childAssocRef.getParentRef(), beforeName);
fireNodeEvent(new MoveNodeEvent( fType, nodeRef, relPath , nodeRef)); String relPath3 = buildRelativePathString(childAssocRef.getParentRef(), afterName);
fireNodeEvent(new MoveNodeEvent( fType, nodeRef, relPath2 , relPath3));
} }
} }
} }
@@ -335,12 +345,15 @@ public class NodeMonitor extends TransactionListenerAdapter
NodeRef oldNodeRef = oldChildAssocRef.getChildRef(); NodeRef oldNodeRef = oldChildAssocRef.getChildRef();
if ( oldNodeRef.getStoreRef().equals( m_storeRef) == false) if ( oldNodeRef.getStoreRef().equals( m_storeRef) == false)
{
return; return;
}
QName nodeType = m_nodeService.getType( oldNodeRef); QName nodeType = m_nodeService.getType( oldNodeRef);
FileFolderServiceType fType = m_fileFolderService.getType( nodeType); FileFolderServiceType fType = m_fileFolderService.getType( nodeType);
if ( fType != FileFolderServiceType.INVALID) { if ( fType != FileFolderServiceType.INVALID)
{
// Get the full path to the file/folder node // Get the full path to the file/folder node
@@ -348,7 +361,8 @@ public class NodeMonitor extends TransactionListenerAdapter
String fName = (String) m_nodeService.getProperty( oldNodeRef, ContentModel.PROP_NAME); String fName = (String) m_nodeService.getProperty( oldNodeRef, ContentModel.PROP_NAME);
// Build the share relative path to the node // Build the share relative path to the node
String relPath = buildRelativePathString(oldChildAssocRef.getParentRef(), oldNodeRef, fName); String relPath = buildRelativePathString(oldChildAssocRef.getParentRef(), fName);
String relPath2 = buildRelativePathString(newChildAssocRef.getParentRef(), fName);
// DEBUG // DEBUG
@@ -361,7 +375,7 @@ public class NodeMonitor extends TransactionListenerAdapter
// Create a move event // Create a move event
NodeEvent nodeEvent = new MoveNodeEvent( fType, oldNodeRef, relPath, newChildAssocRef.getChildRef()); NodeEvent nodeEvent = new MoveNodeEvent( fType, oldNodeRef, relPath, relPath2);
// Store the event in the transaction until committed, and register the transaction listener // Store the event in the transaction until committed, and register the transaction listener
fireNodeEvent(nodeEvent); fireNodeEvent(nodeEvent);
@@ -446,7 +460,7 @@ public class NodeMonitor extends TransactionListenerAdapter
* @param nodeName the old name of the childs * @param nodeName the old name of the childs
* @return * @return
*/ */
private String buildRelativePathString(NodeRef parentNodeRef, NodeRef childNodeRef, String nodeName) { private String buildRelativePathString(NodeRef parentNodeRef, String nodeName) {
Path nodePath = m_nodeService.getPath(parentNodeRef); Path nodePath = m_nodeService.getPath(parentNodeRef);
StringBuilder pathStr = new StringBuilder(); StringBuilder pathStr = new StringBuilder();
@@ -469,7 +483,9 @@ public class NodeMonitor extends TransactionListenerAdapter
private void fireNodeEvent(NodeEvent nodeEvent) { private void fireNodeEvent(NodeEvent nodeEvent) {
String eventKey = FileSysNodeEvent; String eventKey = FileSysNodeEvent;
if ( AlfrescoTransactionSupport.getResource( FileSysNodeEvent) != null) if ( AlfrescoTransactionSupport.getResource( FileSysNodeEvent) != null)
{
eventKey = FileSysNodeEvent2; eventKey = FileSysNodeEvent2;
}
// Store the event in the transaction until committed, and register the transaction listener // Store the event in the transaction until committed, and register the transaction listener
@@ -550,17 +566,16 @@ public class NodeMonitor extends TransactionListenerAdapter
while ( m_shutdown == false) while ( m_shutdown == false)
{ {
try try
{ {
// Wait for an event to process // Wait for an event to process
final NodeEvent nodeEvent = m_eventQueue.removeEvent(); final NodeEvent nodeEvent = m_eventQueue.removeEvent();
// DEBUG if ( logger.isDebugEnabled())
{
if ( logger.isDebugEnabled())
logger.debug("Processing event " + nodeEvent); logger.debug("Processing event " + nodeEvent);
}
// Check for a shutdown // Check for a shutdown
@@ -580,38 +595,26 @@ public class NodeMonitor extends TransactionListenerAdapter
// check for a node delete // check for a node delete
if ( nodeEvent instanceof DeleteNodeEvent) { if ( nodeEvent instanceof DeleteNodeEvent)
{
// Node deleted // Node deleted
processDeleteNode((DeleteNodeEvent) nodeEvent); processDeleteNode((DeleteNodeEvent) nodeEvent);
} }
// Check that the node is still valid
else if (!m_nodeService.exists(nodeEvent.getNodeRef()))
{
return null;
}
// Process the node event, for an existing node // Process the node event, for an existing node
else if ( nodeEvent instanceof CreateNodeEvent)
if ( nodeEvent instanceof CreateNodeEvent) { {
// Node created // Node created
processCreateNode((CreateNodeEvent) nodeEvent); processCreateNode((CreateNodeEvent) nodeEvent);
} }
else if ( nodeEvent instanceof MoveNodeEvent) { else if ( nodeEvent instanceof MoveNodeEvent)
{
// Node moved // Node moved
processMoveNode((MoveNodeEvent) nodeEvent); processMoveNode((MoveNodeEvent) nodeEvent);
} }
else if ( nodeEvent instanceof LockNodeEvent) { else if ( nodeEvent instanceof LockNodeEvent)
{
// Node locked/unlocked // Node locked/unlocked
processLockNode(( LockNodeEvent) nodeEvent); processLockNode(( LockNodeEvent) nodeEvent);
} }
@@ -630,7 +633,7 @@ public class NodeMonitor extends TransactionListenerAdapter
} }
catch (Throwable e) catch (Throwable e)
{ {
logger.error(e); logger.error("Throwable in NodeMonitor thread", e);
} }
} }
} }
@@ -640,13 +643,11 @@ public class NodeMonitor extends TransactionListenerAdapter
* *
* @param createEvent CreateNodeEvent * @param createEvent CreateNodeEvent
*/ */
private final void processCreateNode(NodeEvent createEvent) { private final void processCreateNode(CreateNodeEvent createEvent) {
// Get the full path to the file/folder node // Get the full path to the file/folder node
String relPath = createEvent.getRelPath();
Path nodePath = m_nodeService.getPath( createEvent.getNodeRef()); String name = createEvent.getName();
String relPath = nodePath.toDisplayPath(m_nodeService, m_permissionService);
String fName = (String) m_nodeService.getProperty( createEvent.getNodeRef(), ContentModel.PROP_NAME);
// Check if the path is within the filesystem view // Check if the path is within the filesystem view
@@ -655,14 +656,14 @@ public class NodeMonitor extends TransactionListenerAdapter
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled())
logger.debug("CreateNode nodeRef=" + createEvent.getNodeRef() + ", fName=" + fName + ", path=" + relPath); logger.debug("CreateNode nodeRef=" + createEvent.getNodeRef() + ", fName=" + name + ", path=" + relPath);
// Build the full file path // Build the full file path
StringBuilder fullPath = new StringBuilder(); StringBuilder fullPath = new StringBuilder();
fullPath.append( relPath.substring( m_rootPath.length())); fullPath.append( relPath.substring( m_rootPath.length()));
fullPath.append( "/"); fullPath.append( "/");
fullPath.append( fName); fullPath.append( name);
relPath = fullPath.toString(); relPath = fullPath.toString();
@@ -801,22 +802,8 @@ public class NodeMonitor extends TransactionListenerAdapter
// Strip the root path // Strip the root path
String fromPath = moveEvent.getPath().substring( m_rootPath.length()).replace( '/', '\\'); String fromPath = moveEvent.getFromPath().substring( m_rootPath.length()).replace( '/', '\\');
String toPath = moveEvent.getToPath().substring( m_rootPath.length()).replace( '/', '\\');
// Get the destination relative path
Path nodePath = m_nodeService.getPath( moveEvent.getMoveToNodeRef());
String fName = (String) m_nodeService.getProperty( moveEvent.getMoveToNodeRef(), ContentModel.PROP_NAME);
// Build the share relative path to the destination
StringBuilder pathStr = new StringBuilder();
pathStr.append( nodePath.toDisplayPath(m_nodeService, m_permissionService));
if ( pathStr.charAt(pathStr.length() - 1) != '/' && pathStr.charAt(pathStr.length() - 1) != '\\')
pathStr.append("\\");
pathStr.append( fName);
String toPath = pathStr.toString().substring( m_rootPath.length()).replace( '/', '\\');
// DEBUG // DEBUG
@@ -889,11 +876,10 @@ public class NodeMonitor extends TransactionListenerAdapter
private final void processLockNode(LockNodeEvent lockEvent) { private final void processLockNode(LockNodeEvent lockEvent) {
// Get the full path to the file/folder node // Get the full path to the file/folder node
Path nodePath = m_nodeService.getPath( lockEvent.getNodeRef()); String relPath = lockEvent.getRelPath();
String relPath = nodePath.toDisplayPath(m_nodeService, m_permissionService); String name = lockEvent.getName();
String fName = (String) m_nodeService.getProperty( lockEvent.getNodeRef(), ContentModel.PROP_NAME);
// Check if the path is within the filesystem view // Check if the path is within the filesystem view
if ( relPath.startsWith( m_rootPath)) { if ( relPath.startsWith( m_rootPath)) {
@@ -901,14 +887,16 @@ public class NodeMonitor extends TransactionListenerAdapter
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled())
logger.debug("LockNode nodeRef=" + lockEvent.getNodeRef() + ", fName=" + fName + ", path=" + relPath); {
logger.debug("LockNode nodeRef=" + lockEvent.getNodeRef() + ", name=" + name + ", path=" + relPath);
}
// Build the full file path // Build the full file path
StringBuilder fullPath = new StringBuilder(); StringBuilder fullPath = new StringBuilder();
fullPath.append( relPath.substring( m_rootPath.length())); fullPath.append( relPath.substring( m_rootPath.length()));
fullPath.append( "/"); fullPath.append( "/");
fullPath.append( fName); fullPath.append( name);
relPath = fullPath.toString().replace( '/', '\\'); relPath = fullPath.toString().replace( '/', '\\');