From ea53ffea50c62f0deb2d7af90271a3761bd0ec97 Mon Sep 17 00:00:00 2001 From: Steven Glover Date: Tue, 29 Nov 2011 14:28:39 +0000 Subject: [PATCH] Merged BRANCHES/DEV/V3.4-BUG-FIX to HEAD: 32244: Fix for ALF-11435: 32246: Fix for ALF-11435 (part 2) 32247: Fix for ALF-11435 (part 3) plus make sure that hidden files have the noindex aspect applied git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@32388 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../model-specific-services-context.xml | 37 ++- config/alfresco/model/systemModel.xml | 7 + config/alfresco/public-services-context.xml | 3 +- .../public-services-security-context.xml | 1 + .../org/alfresco/filesys/repo/CifsHelper.java | 23 +- .../alfresco/repo/imap/ImapServiceImpl.java | 4 +- .../filefolder/FileFolderServiceImpl.java | 26 +- .../filefolder/FileFolderServiceImplTest.java | 30 ++ .../repo/model/filefolder/FileInfoImpl.java | 7 + .../FilenameFilteringInterceptor.java | 311 ++++++++++++++++++ .../filefolder/TempFileMarkerInterceptor.java | 132 -------- .../service/cmr/model/FileFolderService.java | 10 +- .../alfresco/service/cmr/model/FileInfo.java | 5 + 13 files changed, 446 insertions(+), 150 deletions(-) create mode 100644 source/java/org/alfresco/repo/model/filefolder/FilenameFilteringInterceptor.java delete mode 100644 source/java/org/alfresco/repo/model/filefolder/TempFileMarkerInterceptor.java diff --git a/config/alfresco/model-specific-services-context.xml b/config/alfresco/model-specific-services-context.xml index 6bccfe082b..92a662a16f 100644 --- a/config/alfresco/model-specific-services-context.xml +++ b/config/alfresco/model-specific-services-context.xml @@ -80,12 +80,8 @@ - - - - - - + + @@ -94,7 +90,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/model/systemModel.xml b/config/alfresco/model/systemModel.xml index 81846d38ee..4c8fa8f95f 100644 --- a/config/alfresco/model/systemModel.xml +++ b/config/alfresco/model/systemModel.xml @@ -155,6 +155,13 @@ false + + + + Hidden + + false + diff --git a/config/alfresco/public-services-context.xml b/config/alfresco/public-services-context.xml index 20077ca526..b978e76ff1 100644 --- a/config/alfresco/public-services-context.xml +++ b/config/alfresco/public-services-context.xml @@ -745,7 +745,6 @@ - org.alfresco.service.cmr.model.FileFolderService @@ -756,12 +755,12 @@ + - diff --git a/config/alfresco/public-services-security-context.xml b/config/alfresco/public-services-security-context.xml index b6b231c612..4ef3de993d 100644 --- a/config/alfresco/public-services-security-context.xml +++ b/config/alfresco/public-services-security-context.xml @@ -432,6 +432,7 @@ org.alfresco.service.cmr.model.FileFolderService.getWriter=ACL_NODE.0.sys:base.WriteContent org.alfresco.service.cmr.model.FileFolderService.exists=ACL_ALLOW org.alfresco.service.cmr.model.FileFolderService.getType=ACL_ALLOW + org.alfresco.service.cmr.model.FileFolderService.removeHiddenFiles=ACL_ALLOW org.alfresco.service.cmr.model.FileFolderService.*=ACL_DENY diff --git a/source/java/org/alfresco/filesys/repo/CifsHelper.java b/source/java/org/alfresco/filesys/repo/CifsHelper.java index e09e45f1c9..7ee260c1e5 100644 --- a/source/java/org/alfresco/filesys/repo/CifsHelper.java +++ b/source/java/org/alfresco/filesys/repo/CifsHelper.java @@ -36,7 +36,6 @@ import org.alfresco.jlan.server.filesys.FileName; import org.alfresco.jlan.server.filesys.FileType; import org.alfresco.jlan.util.WildCard; import org.alfresco.model.ContentModel; -import org.alfresco.repo.model.filefolder.FileFolderServiceImpl; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileFolderUtil; @@ -71,7 +70,7 @@ public class CifsHelper private FileFolderService fileFolderService; private MimetypeService mimetypeService; private PermissionService permissionService; - + private Set excludedTypes = new HashSet(); private boolean isReadOnlyFlagOnFolders = false; @@ -87,8 +86,8 @@ public class CifsHelper { this.dictionaryService = dictionaryService; } - - public void setNodeService(NodeService nodeService) + + public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } @@ -124,7 +123,7 @@ public class CifsHelper this.excludedTypes.add(QName.createQName(exType)); } } - + /** * Controls whether the read only flag is set on folders. This flag, when set, may cause problematic # behaviour in * Windows clients and doesn't necessarily mean a folder can't be written to. See ALF-6727. Should we ever set the @@ -286,6 +285,19 @@ public class CifsHelper if (name != null) { fileInfo.setFileName(name); + + // Check for file names that should be hidden + + if(nodeService.hasAspect(fileInfo.getNodeRef(), ContentModel.ASPECT_HIDDEN)) + { + // Add the hidden file attribute + int attr = fileInfo.getFileAttributes(); + if (( attr & FileAttribute.Hidden) == 0) + { + attr += FileAttribute.Hidden; + fileInfo.setFileAttributes( attr); + } + } } // Read/write access @@ -704,4 +716,5 @@ public class CifsHelper } return false; } + } diff --git a/source/java/org/alfresco/repo/imap/ImapServiceImpl.java b/source/java/org/alfresco/repo/imap/ImapServiceImpl.java index 0bec306546..bbc15440dd 100644 --- a/source/java/org/alfresco/repo/imap/ImapServiceImpl.java +++ b/source/java/org/alfresco/repo/imap/ImapServiceImpl.java @@ -746,7 +746,7 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol this.folderCacheLock.readLock().unlock(); } } - List fileInfos = fileFolderService.listFiles(contextNodeRef); + List fileInfos = fileFolderService.removeHiddenFiles(fileFolderService.listFiles(contextNodeRef)); final NavigableMap currentSearch = new TreeMap(); switch (viewMode) @@ -1047,7 +1047,7 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol // Only list this folder if we have a wildcard name. Otherwise do a direct lookup by name. if (name.contains("*") || name.contains("%")) { - list = fileFolderService.listFolders(root); + list = fileFolderService.removeHiddenFiles(fileFolderService.listFolders(root)); } else { diff --git a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java index 6067eb2a3a..13c50e13e9 100644 --- a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java +++ b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java @@ -256,9 +256,16 @@ public class FileFolderServiceImpl implements FileFolderService // Is it a folder QName typeQName = nodeService.getType(nodeRef); boolean isFolder = isFolder(typeQName); + boolean isHidden = false; + + if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_HIDDEN)) + { + isHidden = true; + } // Construct the file info and add to the results - FileInfo fileInfo = new FileInfoImpl(nodeRef, typeQName, isFolder, properties); + FileInfo fileInfo = new FileInfoImpl(nodeRef, typeQName, isFolder, isHidden, properties); + // Done return fileInfo; } @@ -569,7 +576,7 @@ public class FileFolderServiceImpl implements FileFolderService } return childNodeRef; } - + /** * @see #search(NodeRef, String, boolean, boolean, boolean) */ @@ -1434,4 +1441,19 @@ public class FileFolderServiceImpl implements FileFolderService } return new Pair(base, ext); } + + public List removeHiddenFiles(List files) + { + List ret = new ArrayList(files.size()); + + for(FileInfo file : files) + { + if(!nodeService.hasAspect(file.getNodeRef(), ContentModel.ASPECT_HIDDEN)) + { + ret.add(file); + } + } + + return ret; + } } diff --git a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java index c60be12de3..f2ce806560 100644 --- a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java +++ b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java @@ -33,6 +33,7 @@ import javax.transaction.UserTransaction; import junit.framework.TestCase; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.jlan.server.FileFilterMode; import org.alfresco.model.ContentModel; import org.alfresco.model.ForumModel; import org.alfresco.query.PagingRequest; @@ -1277,6 +1278,35 @@ public class FileFolderServiceImplTest extends TestCase beforeSleep.compareTo((Date)nodeService.getProperty(destinationFolderNodeRef, ContentModel.PROP_MODIFIED)) < 0); } + public void testHiddenFiles() + { + FileFilterMode.setMode(FileFilterMode.Mode.ENHANCED); + + NodeRef parent = fileFolderService.create(rootNodeRef, "New Folder", ContentModel.TYPE_FOLDER).getNodeRef(); + NodeRef child = fileFolderService.create(parent, "file.tmp", ContentModel.TYPE_CONTENT).getNodeRef(); + assertTrue(nodeService.hasAspect(child, ContentModel.ASPECT_TEMPORARY)); + assertTrue(!nodeService.hasAspect(child, ContentModel.ASPECT_HIDDEN)); + + NodeRef parent1 = fileFolderService.create(rootNodeRef, ".TemporaryItems", ContentModel.TYPE_FOLDER).getNodeRef(); + NodeRef child1 = fileFolderService.create(parent1, "file1", ContentModel.TYPE_CONTENT).getNodeRef(); + assertTrue(nodeService.hasAspect(child1, ContentModel.ASPECT_TEMPORARY)); + assertTrue(nodeService.hasAspect(child1, ContentModel.ASPECT_HIDDEN)); + + NodeRef parent2 = fileFolderService.create(rootNodeRef, "Folder 2", ContentModel.TYPE_FOLDER).getNodeRef(); + NodeRef child2 = fileFolderService.create(parent2, "Thumbs.db", ContentModel.TYPE_CONTENT).getNodeRef(); + assertTrue(!nodeService.hasAspect(child2, ContentModel.ASPECT_TEMPORARY)); + assertTrue(nodeService.hasAspect(child2, ContentModel.ASPECT_HIDDEN)); + + List children = fileFolderService.list(parent); + assertEquals(1, children.size()); + + children = fileFolderService.list(parent1); + assertEquals(1, children.size()); + + children = fileFolderService.list(parent2); + assertEquals(1, children.size()); + } + public void testPatterns() { // sanity checks only (see also GetChildrenCannedQueryTest) diff --git a/source/java/org/alfresco/repo/model/filefolder/FileInfoImpl.java b/source/java/org/alfresco/repo/model/filefolder/FileInfoImpl.java index e339a50e52..af7eb7ea93 100644 --- a/source/java/org/alfresco/repo/model/filefolder/FileInfoImpl.java +++ b/source/java/org/alfresco/repo/model/filefolder/FileInfoImpl.java @@ -42,6 +42,7 @@ public class FileInfoImpl implements FileInfo private NodeRef linkNodeRef; private boolean isFolder; private boolean isLink; + private boolean isHindden; private Map properties; private QName typeQName; @@ -52,6 +53,7 @@ public class FileInfoImpl implements FileInfo NodeRef nodeRef, QName typeQName, boolean isFolder, + boolean isHidden, Map properties) { this.nodeRef = nodeRef; @@ -59,6 +61,7 @@ public class FileInfoImpl implements FileInfo this.isFolder = isFolder; this.properties = properties; + this.isHindden = isHidden; // Check if this is a link node if ( properties.containsKey( ContentModel.PROP_LINK_DESTINATION)) @@ -135,6 +138,10 @@ public class FileInfoImpl implements FileInfo return isLink; } + public boolean isHidden() { + return isHindden; + } + public NodeRef getLinkNodeRef() { return linkNodeRef; diff --git a/source/java/org/alfresco/repo/model/filefolder/FilenameFilteringInterceptor.java b/source/java/org/alfresco/repo/model/filefolder/FilenameFilteringInterceptor.java new file mode 100644 index 0000000000..a823e58e07 --- /dev/null +++ b/source/java/org/alfresco/repo/model/filefolder/FilenameFilteringInterceptor.java @@ -0,0 +1,311 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . */ +package org.alfresco.repo.model.filefolder; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.alfresco.jlan.server.FileFilterMode; +import org.alfresco.jlan.server.FileFilterMode.Mode; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.Path; +import org.alfresco.service.cmr.repository.Path.Element; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.PatternFilter; +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * An interceptor that intercepts the FileFolderService create method, creating files and folders as the system user + * and applying temporary and hidden aspects when they match a pattern. + * + */ +public class FilenameFilteringInterceptor implements MethodInterceptor +{ + private static Log logger = LogFactory.getLog(FilenameFilteringInterceptor.class); + + private NodeService nodeService; + private PermissionService permissionService; + + private PatternFilter temporaryFiles; + private PatternFilter hiddenFiles; + private PatternFilter systemPaths; + + public FilenameFilteringInterceptor() + { + } + + /** + * A list of regular expressions that represent patterns of hidden files. + * + */ + public void setHiddenFiles(PatternFilter hiddenFiles) + { + this.hiddenFiles = hiddenFiles; + } + + /** + * A list of regular expressions that represent patterns of temporary files. + * + */ + public void setTemporaryFiles(PatternFilter temporaryFiles) + { + this.temporaryFiles = temporaryFiles; + } + + /** + * A list of regular expressions that represent patterns of system paths. + * + */ + public void setSystemPaths(PatternFilter systemPaths) + { + this.systemPaths = systemPaths; + } + + public Mode getMode() + { + return FileFilterMode.getMode(); + } + + /** + * @param nodeService the service to use to apply the sys:temporary aspect + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setPermissionService(PermissionService permissionService) + { + this.permissionService = permissionService; + } + + private void checkTemporaryAspect(boolean isTemporary, FileInfo fileInfo) + { + NodeRef nodeRef = fileInfo.getNodeRef(); + + if(isTemporary) + { + // it matched, so apply the temporary and hidden aspects + nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null); + + if (logger.isDebugEnabled()) + { + logger.debug("Applied temporary marker: " + fileInfo); + } + } + else + { + // If there was NOT a match then the file should not be marked as temporary + // after any of the operations in question. + if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TEMPORARY)) + { + // Remove the aspect + nodeService.removeAspect(nodeRef, ContentModel.ASPECT_TEMPORARY); + + if (logger.isDebugEnabled()) + { + logger.debug("Removed temporary marker: " + fileInfo); + } + } + } + } + + private void checkHiddenAspect(boolean isHidden, FileInfo fileInfo) + { + NodeRef nodeRef = fileInfo.getNodeRef(); + + if (isHidden) + { + nodeService.addAspect(nodeRef, ContentModel.ASPECT_HIDDEN, null); + + Map props = new HashMap(2); + props.put(ContentModel.PROP_IS_INDEXED, Boolean.FALSE); + props.put(ContentModel.PROP_IS_CONTENT_INDEXED, Boolean.FALSE); + nodeService.addAspect(nodeRef, ContentModel.ASPECT_INDEX_CONTROL, props); + + if (logger.isDebugEnabled()) + { + logger.debug("Applied hidden marker: " + fileInfo); + } + } + else + { + if(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_HIDDEN)) + { + // Remove the aspect + nodeService.removeAspect(nodeRef, ContentModel.ASPECT_HIDDEN); + + if (logger.isDebugEnabled()) + { + logger.debug("Removed hidden marker: " + fileInfo); + } + } + } + } + + private void addIndexedAspect(FileInfo fileInfo) + { + NodeRef nodeRef = fileInfo.getNodeRef(); + + Map props = new HashMap(2); + props.put(ContentModel.PROP_IS_INDEXED, Boolean.FALSE); + props.put(ContentModel.PROP_IS_CONTENT_INDEXED, Boolean.FALSE); + nodeService.addAspect(nodeRef, ContentModel.ASPECT_INDEX_CONTROL, props); + } + + private Object runAsSystem(MethodInvocation invocation) throws Throwable + { + Object ret = null; + + // We're creating in enhanced mode and have a matching filename or path. Switch to + // the system user to do the operation. + + AuthenticationUtil.pushAuthentication(); + try + { + AuthenticationUtil.setRunAsUserSystem(); + ret = invocation.proceed(); + } + finally + { + AuthenticationUtil.popAuthentication(); + } + + return ret; + } + + private boolean isSystemPath(NodeRef parentNodeRef, String filename) + { + boolean ret = false; + Path path = nodeService.getPath(parentNodeRef); + + Iterator it = path.iterator(); + while(it.hasNext()) + { + Path.ChildAssocElement elem = (Path.ChildAssocElement)it.next(); + QName qname = elem.getRef().getQName(); + if(qname != null && systemPaths.isFiltered(qname.getLocalName())) + { + ret = true; + break; + } + } + + return ret; + } + + public Object invoke(final MethodInvocation invocation) throws Throwable + { + // execute and get the result + String methodName = invocation.getMethod().getName(); + Object ret = null; + + // 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); + permissionService.setPermission(((FileInfo)ret).getNodeRef(), PermissionService.ALL_AUTHORITIES, PermissionService.FULL_CONTROL, true); + + // it's always marked temporary and hidden + checkTemporaryAspect(true, (FileInfo)ret); + checkHiddenAspect(true, (FileInfo)ret); + addIndexedAspect((FileInfo)ret); + } + else + { + // it's not a temporary file/folder, create as normal + ret = invocation.proceed(); + + // if it's on a temporary path check whether temporary and hidden aspects need to be applied + if(isSystemPath(nodeRef, filename)) + { + checkTemporaryAspect(true, (FileInfo)ret); + checkHiddenAspect(true, (FileInfo)ret); + addIndexedAspect((FileInfo)ret); + } + else + { + checkTemporaryAspect(temporaryFiles.isFiltered(filename), (FileInfo)ret); + boolean isHidden = hiddenFiles.isFiltered(filename); + checkHiddenAspect(isHidden, (FileInfo)ret); + if(isHidden) + { + addIndexedAspect((FileInfo)ret); + } + } + } + } + else + { + ret = invocation.proceed(); + + checkTemporaryAspect(temporaryFiles.isFiltered(filename), (FileInfo)ret); + } + } + else if (methodName.startsWith("rename") || + methodName.startsWith("move") || + methodName.startsWith("copy")) + { + ret = invocation.proceed(); + + FileInfo fileInfo = (FileInfo) ret; + String filename = fileInfo.getName(); + + if (logger.isDebugEnabled()) + { + logger.debug("Checking filename returned by " + methodName + ": " + filename); + } + + // check against all the regular expressions + checkTemporaryAspect(temporaryFiles.isFiltered(filename), fileInfo); + + boolean isHidden = hiddenFiles.isFiltered(filename); + checkHiddenAspect(isHidden, fileInfo); + if(isHidden) + { + addIndexedAspect((FileInfo)ret); + } + } + else + { + ret = invocation.proceed(); + } + + // done + return ret; + } +} + diff --git a/source/java/org/alfresco/repo/model/filefolder/TempFileMarkerInterceptor.java b/source/java/org/alfresco/repo/model/filefolder/TempFileMarkerInterceptor.java deleted file mode 100644 index 722e1c296b..0000000000 --- a/source/java/org/alfresco/repo/model/filefolder/TempFileMarkerInterceptor.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.model.filefolder; - -import java.util.Collections; -import java.util.List; - -import org.alfresco.model.ContentModel; -import org.alfresco.service.cmr.model.FileInfo; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * An interceptor for the {@link org.alfresco.service.cmr.model.FileFolderService FileFolderService} - * that marks files or folders with the sys:temporary aspect depending on the - * name pattern {@link #setFilterRegularExpressions(List) provided}. - * - * @author Derek Hulley - */ -public class TempFileMarkerInterceptor implements MethodInterceptor -{ - private static Log logger = LogFactory.getLog(TempFileMarkerInterceptor.class); - - private NodeService nodeService; - private List filterRegularExpressions; - - public TempFileMarkerInterceptor() - { - filterRegularExpressions = Collections.emptyList(); - } - - /** - * @param nodeService the service to use to apply the sys:temporary aspect - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * A list of regular expressions that represent patterns of temporary files. - * - * @param regexps list of regular expressions - * - * @see String#matches(java.lang.String) - */ - public void setFilterRegularExpressions(List regexps) - { - this.filterRegularExpressions = regexps; - } - - /** - * Handles rename, move, copy - */ - public Object invoke(MethodInvocation invocation) throws Throwable - { - Object ret = invocation.proceed(); - - // execute and get the result - String methodName = invocation.getMethod().getName(); - if (methodName.startsWith("create") || - methodName.startsWith("rename") || - methodName.startsWith("move") || - methodName.startsWith("copy")) - { - FileInfo fileInfo = (FileInfo) ret; - String filename = fileInfo.getName(); - NodeRef nodeRef = fileInfo.getNodeRef(); - - if (logger.isDebugEnabled()) - { - logger.debug("Checking filename returned by " + methodName + ": " + filename); - } - - // check against all the regular expressions - boolean matched = false; - for (String regexp : filterRegularExpressions) - { - if (!filename.matches(regexp)) - { - // it is not a match - try next one - continue; - } - else - { - matched = true; - // it matched, so apply the aspect - nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null); - // no further checking required - if (logger.isDebugEnabled()) - { - logger.debug("Applied temporary marker: " + fileInfo); - } - break; - } - } - // If there was NOT a match then the file should not be marked as temporary - // after any of the operations in question. - if (!matched && nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TEMPORARY)) - { - // Remove the aspect - nodeService.removeAspect(nodeRef, ContentModel.ASPECT_TEMPORARY); - if (logger.isDebugEnabled()) - { - logger.debug("Removed temporary marker: " + fileInfo); - } - } - } - // done - return ret; - } -} diff --git a/source/java/org/alfresco/service/cmr/model/FileFolderService.java b/source/java/org/alfresco/service/cmr/model/FileFolderService.java index cf0173e8e9..a3395905fd 100644 --- a/source/java/org/alfresco/service/cmr/model/FileFolderService.java +++ b/source/java/org/alfresco/service/cmr/model/FileFolderService.java @@ -53,7 +53,7 @@ public interface FileFolderService */ @Auditable(parameters = {"contextNodeRef"}) public List list(NodeRef contextNodeRef); - + /** * Lists page of immediate child files and/or folders of the given context node * with optional filtering (exclusion of certain child file/folder subtypes) and sorting @@ -396,4 +396,12 @@ public interface FileFolderService */ @Auditable(parameters = {"typeQName"}) public FileFolderServiceType getType(QName typeQName); + + /** + * Removes any hidden files from the file list. + * + * @param files + * @return a list of files with hidden files removed + */ + public List removeHiddenFiles(List files); } diff --git a/source/java/org/alfresco/service/cmr/model/FileInfo.java b/source/java/org/alfresco/service/cmr/model/FileInfo.java index d5daf2a45e..2330ab7da5 100644 --- a/source/java/org/alfresco/service/cmr/model/FileInfo.java +++ b/source/java/org/alfresco/service/cmr/model/FileInfo.java @@ -52,6 +52,11 @@ public interface FileInfo extends PermissionCheckValue, Serializable */ public boolean isLink(); + /** + * @return true if this instance represents a hidden file + */ + public boolean isHidden(); + /** * @return Return the reference to the node that this node is linked to */