diff --git a/source/java/org/alfresco/repo/model/filefolder/FilenameFilteringInterceptor.java b/source/java/org/alfresco/repo/model/filefolder/FilenameFilteringInterceptor.java index 1b498eef16..54b62690a7 100644 --- a/source/java/org/alfresco/repo/model/filefolder/FilenameFilteringInterceptor.java +++ b/source/java/org/alfresco/repo/model/filefolder/FilenameFilteringInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2012 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -46,6 +46,7 @@ import org.apache.commons.logging.LogFactory; * An interceptor that intercepts FileFolderService methods, ensuring system, temporary and hidden files * and paths are marked with the correct aspects. * + * @author alex.mukha */ public class FilenameFilteringInterceptor implements MethodInterceptor { @@ -219,158 +220,161 @@ public class FilenameFilteringInterceptor implements MethodInterceptor public Object invoke(final MethodInvocation invocation) throws Throwable { + if (!enabled) + { + return invocation.proceed(); + } + // execute and get the result String methodName = invocation.getMethod().getName(); Object ret = null; - if(enabled) + // do the invocation + if (methodName.startsWith("create")) { - // do the invocation - if (methodName.startsWith("create")) - { - NodeRef nodeRef = (NodeRef)invocation.getArguments()[0]; - String filename = (String)invocation.getArguments()[1]; - - if(getMode() == Mode.ENHANCED) - { - if(systemPaths.isFiltered(filename)) - { - // it's a system file/folder, create as system and allow full control to all authorities - ret = runAsSystem(invocation); - FileInfoImpl fileInfo = (FileInfoImpl)ret; - permissionService.setPermission(fileInfo.getNodeRef(), PermissionService.ALL_AUTHORITIES, PermissionService.FULL_CONTROL, true); + NodeRef nodeRef = (NodeRef)invocation.getArguments()[0]; + String filename = (String)invocation.getArguments()[1]; - // it's always marked temporary and hidden - checkTemporaryAspect(true, fileInfo); + if(getMode() == Mode.ENHANCED) + { + if(systemPaths.isFiltered(filename)) + { + // it's a system file/folder, create as system and allow full control to all authorities + ret = runAsSystem(invocation); + FileInfoImpl fileInfo = (FileInfoImpl)ret; + permissionService.setPermission(fileInfo.getNodeRef(), PermissionService.ALL_AUTHORITIES, PermissionService.FULL_CONTROL, true); + + // it's always marked temporary and hidden + checkTemporaryAspect(true, fileInfo); hiddenAspect.hideNode(fileInfo, getSystemFileVisibilityMask(), false, false, false); - } - else - { - // it's not a temporary file/folder, create as normal - ret = invocation.proceed(); - - FileInfoImpl fileInfo = (FileInfoImpl)ret; - - if(isSystemPath(nodeRef, filename)) - { - // it's on a system path, check whether temporary, hidden and noindex aspects need to be applied - checkTemporaryAspect(true, fileInfo); - hiddenAspect.hideNode(fileInfo, getSystemFileVisibilityMask(), false, false, false); - } - else - { - // check whether it's a temporary or hidden file - FileInfo sourceInfo = (FileInfo)ret; - checkTemporaryAspect(isNameOfTmporaryObject(filename, sourceInfo.getNodeRef()), sourceInfo); - boolean isHidden = hiddenAspect.checkHidden(fileInfo, false, false); - if(isHidden && fileInfo instanceof FileInfoImpl) - { - ((FileInfoImpl)fileInfo).setHidden(true); - } - } - } } else { + // it's not a temporary file/folder, create as normal ret = invocation.proceed(); - + FileInfoImpl fileInfo = (FileInfoImpl)ret; - - checkTemporaryAspect(isNameOfTmporaryObject(filename, fileInfo.getNodeRef()), fileInfo); - } - } - else if (methodName.startsWith("move")) - { - Object[] args = invocation.getArguments(); - NodeRef sourceNodeRef = (NodeRef)args[0]; - String newName = (String)args[args.length -1]; - - if(newName != null) - { - // Name is changing - // check against all the regular expressions - checkTemporaryAspect(isNameOfTmporaryObject(newName, sourceNodeRef), sourceNodeRef); - } - - // now do the move - ret = invocation.proceed(); - if(getMode() == Mode.ENHANCED) - { - hiddenAspect.checkHidden(sourceNodeRef, true, true); - } - } - else if (methodName.startsWith("copy")) - { - ret = invocation.proceed(); - - FileInfoImpl fileInfo = (FileInfoImpl) ret; - String filename = fileInfo.getName(); - - if (logger.isDebugEnabled()) - { - logger.debug("Checking filename returned by " + methodName + ": " + filename); - } - - // check against all the regular expressions - checkTemporaryAspect(isNameOfTmporaryObject(filename, fileInfo.getNodeRef()), fileInfo); - if(getMode() == Mode.ENHANCED) - { - boolean isHidden = hiddenAspect.checkHidden(fileInfo, true, true); - if(isHidden && fileInfo instanceof FileInfoImpl) + if(isSystemPath(nodeRef, filename)) { - ((FileInfoImpl)fileInfo).setHidden(true); + // it's on a system path, check whether temporary, hidden and noindex aspects need to be applied + checkTemporaryAspect(true, fileInfo); + hiddenAspect.hideNode(fileInfo, getSystemFileVisibilityMask(), false, false, false); } - } - /* - * TODO should these two calls be before the proceed? However its the same problem as create - * The node needs to be created before we can add aspects. - */ - } - else if (methodName.startsWith("rename")) - { - Object[] args = invocation.getArguments(); - - if(args != null && args.length == 2) - { - /** - * Expecting rename(NodeRef, newName) - */ - String newName = (String)args[1]; - NodeRef sourceNodeRef = (NodeRef)args[0]; - - if (logger.isDebugEnabled()) + else { - logger.debug("Checking filename returned by " + methodName + ": " + newName); - } - - // check against all the regular expressions - checkTemporaryAspect(isNameOfTmporaryObject(newName, sourceNodeRef), sourceNodeRef); - - ret = invocation.proceed(); - - if(getMode() == Mode.ENHANCED) - { - boolean isHidden = hiddenAspect.checkHidden(sourceNodeRef, true, true); - if(isHidden && ret instanceof FileInfoImpl) + // check whether it's a temporary or hidden file + FileInfo sourceInfo = (FileInfo)ret; + boolean isTmp = isTemporaryObject(filename, sourceInfo.getNodeRef()); + checkTemporaryAspect(isTmp, sourceInfo); + boolean isHidden = hiddenAspect.checkHidden(fileInfo, false, false); + if(isHidden && fileInfo instanceof FileInfoImpl) { - ((FileInfoImpl)ret).setHidden(true); + ((FileInfoImpl)fileInfo).setHidden(true); } } - - return ret; - } - else - { - /** - * expected rename(NodeRef, String) - got something else... - */ - throw new AlfrescoRuntimeException("FilenameFilteringInterceptor: unknown rename method"); } } else { ret = invocation.proceed(); + + FileInfoImpl fileInfo = (FileInfoImpl)ret; + + boolean isTmp = isTemporaryObject(filename, fileInfo.getNodeRef()); + checkTemporaryAspect(isTmp, fileInfo); + } + } + else if (methodName.startsWith("move")) + { + Object[] args = invocation.getArguments(); + NodeRef sourceNodeRef = (NodeRef)args[0]; + String newName = (String)args[args.length -1]; + + if(newName != null) + { + // Name is changing + // check against all the regular expressions + boolean isTmp = isTemporaryObject(newName, sourceNodeRef); + checkTemporaryAspect(isTmp, sourceNodeRef); + } + + // now do the move + ret = invocation.proceed(); + + if(getMode() == Mode.ENHANCED) + { + hiddenAspect.checkHidden(sourceNodeRef, true, true); + } + } + else if (methodName.startsWith("copy")) + { + ret = invocation.proceed(); + + FileInfoImpl fileInfo = (FileInfoImpl) ret; + String filename = fileInfo.getName(); + + if (logger.isDebugEnabled()) + { + logger.debug("Checking filename returned by " + methodName + ": " + filename); + } + + // check against all the regular expressions + boolean isTmp = isTemporaryObject(filename, fileInfo.getNodeRef()); + checkTemporaryAspect(isTmp, fileInfo); + if(getMode() == Mode.ENHANCED) + { + boolean isHidden = hiddenAspect.checkHidden(fileInfo, true, true); + if(isHidden && fileInfo instanceof FileInfoImpl) + { + ((FileInfoImpl)fileInfo).setHidden(true); + } + } + /* + * TODO should these two calls be before the proceed? However its the same problem as create + * The node needs to be created before we can add aspects. + */ + } + else if (methodName.startsWith("rename")) + { + Object[] args = invocation.getArguments(); + + if(args != null && args.length == 2) + { + /** + * Expecting rename(NodeRef, newName) + */ + String newName = (String)args[1]; + NodeRef sourceNodeRef = (NodeRef)args[0]; + + if (logger.isDebugEnabled()) + { + logger.debug("Checking filename returned by " + methodName + ": " + newName); + } + + // check against all the regular expressions + boolean isTmp = isTemporaryObject(newName, sourceNodeRef); + checkTemporaryAspect(isTmp, sourceNodeRef); + + ret = invocation.proceed(); + + if(getMode() == Mode.ENHANCED) + { + boolean isHidden = hiddenAspect.checkHidden(sourceNodeRef, true, true); + if(isHidden && ret instanceof FileInfoImpl) + { + ((FileInfoImpl)ret).setHidden(true); + } + } + + return ret; + } + else + { + /** + * expected rename(NodeRef, String) - got something else... + */ + throw new AlfrescoRuntimeException("FilenameFilteringInterceptor: unknown rename method"); } } else @@ -383,33 +387,45 @@ public class FilenameFilteringInterceptor implements MethodInterceptor } /** - * Determines whether specified name matches any pattern of temporary file names. Also it checks special case of new XLS document creation in MacOS. See ALF-14078 (comment added on 04-September-12 04:11 PM) for more details + * Determines whether specified name matches any pattern of temporary file names. + *
Also it checks special case of new XLS document creation in MacOS: + * * * @param name - {@link String} value which contains name of node * @param nodeRef - {@link NodeRef} instance of the node - * @return {@link Boolean} value. true if name is name of temporary object including special case of XLSX in MacOS. false in other case + * @return {@link boolean} value. true if name is name of temporary object. */ - private boolean isNameOfTmporaryObject(String name, NodeRef nodeRef) + private boolean isTemporaryObject(String name, NodeRef nodeRef) { - boolean result = temporaryFiles.isFiltered(name); - - if (!result) + boolean isFiltered = temporaryFiles.isFiltered(name); + if (isFiltered) { - // This pattern must be validated in conjunction with mimetype validation only! - result = XSL_MACOS_TEMPORARY_FILENAME_FITLER.matcher(name).matches(); + return true; + } + + // This pattern must be validated in conjunction with mimetype validation only! + boolean result = XSL_MACOS_TEMPORARY_FILENAME_FITLER.matcher(name).matches(); - if (result && !name.startsWith(MACOS_TEMPORARY_FILE_NAME_PREFIX)) + if (result && !name.startsWith(MACOS_TEMPORARY_FILE_NAME_PREFIX)) + { + ContentReader contentReader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT); + + if (null != contentReader) { - ContentReader contentReader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT); - - if (null != contentReader) - { - result = XLSX_MIMETYPE.equals(contentReader.getMimetype()); - } + result = XLSX_MIMETYPE.equals(contentReader.getMimetype()); + } + else + { + // MNT-10561 + // We are unable to determine the mimetype so assume it's NOT temporary + result = false; } } - return result; } } diff --git a/source/test-java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java b/source/test-java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java index a2d6fa3d4f..9d26529b3b 100644 --- a/source/test-java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java +++ b/source/test-java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2012 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -414,6 +414,24 @@ public class FileFolderServiceImplTest extends TestCase assertNotNull("Folder info for new name is not present", checkInfo); } + /** + * Test for MNT-10561. Renames a folder to a name with the pattern "^[0-9,a-f]{8}$" + */ + public void testRenamePattern() throws Exception + { + FileInfo folderInfo = getByName(NAME_L0_FOLDER_A, true); + assertNotNull(folderInfo); + // rename normal + String newName = "abcd1234"; + folderInfo = fileFolderService.rename(folderInfo.getNodeRef(), newName); + // check it + FileInfo checkInfo = getByName(NAME_L0_FOLDER_A, true); + assertNull("Folder info should have been renamed away", checkInfo); + checkInfo = getByName(newName, true); + assertNotNull("Folder info for new name is not present", checkInfo); + assertFalse(nodeService.getAspects(checkInfo.getNodeRef()).contains(ContentModel.ASPECT_TEMPORARY)); + } + public void testRenameWithoutAssocQNameChange() throws Exception { FileInfo folderInfo = getByName(NAME_L0_FOLDER_A, true);