Cascade hidden aspect for remame, copy, move

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@33096 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Steven Glover
2012-01-08 10:19:24 +00:00
parent 4b8f097c7f
commit 067faf5fdf
7 changed files with 404 additions and 123 deletions

View File

@@ -12,6 +12,9 @@
<bean name="hiddenAspect" class="org.alfresco.repo.model.filefolder.HiddenAspect"> <bean name="hiddenAspect" class="org.alfresco.repo.model.filefolder.HiddenAspect">
<property name="nodeService" ref="NodeService"/> <property name="nodeService" ref="NodeService"/>
<property name="fileFolderService" ref="fileFolderService"/>
<property name="searchService" ref="searchService"/>
<property name="patterns"> <property name="patterns">
<list> <list>
<bean class="org.alfresco.repo.model.filefolder.HiddenFileFilter"> <bean class="org.alfresco.repo.model.filefolder.HiddenFileFilter">
@@ -138,6 +141,7 @@
<property name="systemPaths" ref="systemPaths" /> <property name="systemPaths" ref="systemPaths" />
<property name="hiddenAspect" ref="hiddenAspect" /> <property name="hiddenAspect" ref="hiddenAspect" />
<property name="temporaryFiles" ref="temporaryFiles" /> <property name="temporaryFiles" ref="temporaryFiles" />
<property name="enabled" value="${fileFolderService.checkHidden.enabled}" />
</bean> </bean>
<!-- Multilingual specific service --> <!-- Multilingual specific service -->

View File

@@ -816,3 +816,4 @@ system.content.caching.maxFileSizeMB=0
mybatis.useLocalCaches=false mybatis.useLocalCaches=false
fileFolderService.checkHidden.enabled=true

View File

@@ -619,7 +619,7 @@ public class ImporterComponent
} }
// check whether the node should be hidden // check whether the node should be hidden
hiddenAspect.checkHidden(nodeRef); hiddenAspect.checkHidden(nodeRef, false);
// import content, if applicable // import content, if applicable
for (Map.Entry<QName,Serializable> property : context.getProperties().entrySet()) for (Map.Entry<QName,Serializable> property : context.getProperties().entrySet())

View File

@@ -53,6 +53,7 @@ public class FilenameFilteringInterceptor implements MethodInterceptor
private PatternFilter temporaryFiles; private PatternFilter temporaryFiles;
private PatternFilter systemPaths; private PatternFilter systemPaths;
private HiddenAspect hiddenAspect; private HiddenAspect hiddenAspect;
private boolean enabled = true;
public FilenameFilteringInterceptor() public FilenameFilteringInterceptor()
{ {
@@ -72,6 +73,11 @@ public class FilenameFilteringInterceptor implements MethodInterceptor
this.hiddenAspect = hiddenAspect; this.hiddenAspect = hiddenAspect;
} }
public void setEnabled(boolean enabled)
{
this.enabled = enabled;
}
/** /**
* A list of regular expressions that represent patterns of system paths. * A list of regular expressions that represent patterns of system paths.
* *
@@ -192,6 +198,8 @@ public class FilenameFilteringInterceptor implements MethodInterceptor
String methodName = invocation.getMethod().getName(); String methodName = invocation.getMethod().getName();
Object ret = null; Object ret = null;
if(enabled)
{
// do the invocation // do the invocation
if (methodName.startsWith("create")) if (methodName.startsWith("create"))
{ {
@@ -228,7 +236,7 @@ public class FilenameFilteringInterceptor implements MethodInterceptor
{ {
// check whether it's a temporary or hidden file // check whether it's a temporary or hidden file
checkTemporaryAspect(temporaryFiles.isFiltered(filename), (FileInfo)ret); checkTemporaryAspect(temporaryFiles.isFiltered(filename), (FileInfo)ret);
hiddenAspect.checkHidden(fileInfo); hiddenAspect.checkHidden(fileInfo, false);
} }
} }
} }
@@ -259,7 +267,12 @@ public class FilenameFilteringInterceptor implements MethodInterceptor
checkTemporaryAspect(temporaryFiles.isFiltered(filename), fileInfo); checkTemporaryAspect(temporaryFiles.isFiltered(filename), fileInfo);
if(getMode() == Mode.ENHANCED) if(getMode() == Mode.ENHANCED)
{ {
hiddenAspect.checkHidden(fileInfo); hiddenAspect.checkHidden(fileInfo, true);
}
}
else
{
ret = invocation.proceed();
} }
} }
else else

View File

@@ -6,15 +6,25 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.Path.Element; import org.alfresco.service.cmr.repository.Path.Element;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.FileFilterMode.Client; import org.alfresco.util.FileFilterMode.Client;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@@ -78,9 +88,11 @@ public class HiddenAspect
} }
}; };
private List<HiddenFileInfoImpl> filters = new ArrayList<HiddenFileInfoImpl>(10); private List<HiddenFileInfo> filters = new ArrayList<HiddenFileInfo>(10);
private NodeService nodeService; private NodeService nodeService;
private FileFolderService fileFolderService;
private SearchService searchService;
public HiddenAspect() public HiddenAspect()
{ {
@@ -91,6 +103,16 @@ public class HiddenAspect
this.nodeService = nodeService; this.nodeService = nodeService;
} }
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
public void setPatterns(List<HiddenFileFilter> filters) public void setPatterns(List<HiddenFileFilter> filters)
{ {
for(HiddenFileFilter filter : filters) for(HiddenFileFilter filter : filters)
@@ -99,11 +121,49 @@ public class HiddenAspect
} }
} }
public List<HiddenFileInfo> getPatterns()
{
return filters;
}
public Client[] getClients() public Client[] getClients()
{ {
return Client.values(); return Client.values();
} }
private ResultSet searchForName(StoreRef storeRef, String name)
{
SearchParameters sp = new SearchParameters();
sp.addStore(storeRef);
sp.setLanguage("lucene");
sp.setQuery("@" + LuceneQueryParser.escape(ContentModel.PROP_NAME.toString()) + ":\"" + name + "\"");
sp.addLocale(new Locale("en"));
return searchService.query(sp);
}
/**
* Searches for nodes in the given store that should be hidden (i.e. match the hidden pattern)
* and hides them if they are not already hidden.
*
* @param storeRef
*/
public void checkHidden(StoreRef storeRef)
{
for(HiddenFileInfo filter : filters)
{
String pattern = filter.getFilter();
ResultSet rs = searchForName(storeRef, pattern);
for(NodeRef nodeRef : rs.getNodeRefs())
{
if(!hasHiddenAspect(nodeRef))
{
hideNode(nodeRef, filter.getVisibilityMask());
}
}
}
}
private Integer getClientIndex(Client client) private Integer getClientIndex(Client client)
{ {
return client.ordinal(); return client.ordinal();
@@ -177,9 +237,9 @@ public class HiddenAspect
private HiddenFileInfo isHidden(String path) private HiddenFileInfo isHidden(String path)
{ {
// check against all the filters // check against all the filters
HiddenFileInfoImpl matched = null; HiddenFileInfo matched = null;
for(HiddenFileInfoImpl filter : filters) for(HiddenFileInfo filter : filters)
{ {
if(filter.isHidden(path)) if(filter.isHidden(path))
{ {
@@ -191,6 +251,11 @@ public class HiddenAspect
return matched; return matched;
} }
private boolean hasHiddenAspect(NodeRef nodeRef)
{
return nodeService.hasAspect(nodeRef, ContentModel.ASPECT_HIDDEN);
}
public int getClientVisibilityMask(Client client, Visibility visibility) public int getClientVisibilityMask(Client client, Visibility visibility)
{ {
return visibility.getMask() << getClientIndex(client)*2; return visibility.getMask() << getClientIndex(client)*2;
@@ -202,7 +267,7 @@ public class HiddenAspect
* @param nodeRef * @param nodeRef
* @return the matching filter, or null if no match * @return the matching filter, or null if no match
*/ */
public HiddenFileInfo isHidden(NodeRef nodeRef) public HiddenFileInfo onHiddenPath(NodeRef nodeRef)
{ {
HiddenFileInfo ret = null; HiddenFileInfo ret = null;
// TODO would be nice to check each part of the path in turn, bailing out if a match is found // TODO would be nice to check each part of the path in turn, bailing out if a match is found
@@ -259,10 +324,10 @@ public class HiddenAspect
* @param fileInfo * @param fileInfo
* @return * @return
*/ */
public void checkHidden(FileInfoImpl fileInfo) public void checkHidden(FileInfoImpl fileInfo, boolean cascade)
{ {
NodeRef nodeRef = fileInfo.getNodeRef(); NodeRef nodeRef = fileInfo.getNodeRef();
HiddenFileInfo hiddenFileInfo = checkHidden(nodeRef); HiddenFileInfo hiddenFileInfo = checkHidden(nodeRef, cascade);
if(hiddenFileInfo != null) if(hiddenFileInfo != null)
{ {
fileInfo.setHidden(true); fileInfo.setHidden(true);
@@ -283,21 +348,80 @@ public class HiddenAspect
fileInfo.setHidden(true); fileInfo.setHidden(true);
} }
private void applyHidden(NodeRef nodeRef, int visibilityMask)
{
PagingRequest pagingRequest = new PagingRequest(0, Integer.MAX_VALUE, null);
PagingResults<FileInfo> results = fileFolderService.list(nodeRef, true, true, null, null, pagingRequest);
List<FileInfo> files = results.getPage();
// apply the hidden aspect to all folders and folders and then recursively to all sub-folders, unless the sub-folder
// already has the hidden aspect applied (it may have been applied for a different pattern).
for(FileInfo file : files)
{
if(!hasHiddenAspect(file.getNodeRef()))
{
hideNode(file.getNodeRef(), visibilityMask);
}
if(file.isFolder())
{
applyHidden(file.getNodeRef(), visibilityMask);
}
}
}
private void removeHidden(NodeRef nodeRef)
{
PagingRequest pagingRequest = new PagingRequest(0, Integer.MAX_VALUE, null);
PagingResults<FileInfo> results = fileFolderService.list(nodeRef, true, true, null, null, pagingRequest);
List<FileInfo> files = results.getPage();
for(FileInfo file : files)
{
String name = (String)nodeService.getProperty(file.getNodeRef(), ContentModel.PROP_NAME);
// remove hidden aspect only if it doesn't match a hidden pattern
if(isHidden(name) == null)
{
removeHiddenAspect(file.getNodeRef());
removeIndexControlAspect(file.getNodeRef());
if(file.isFolder())
{
removeHidden(file.getNodeRef());
}
}
}
}
/** /**
* Checks whether the file should be hidden and applies the hidden and not indexed aspects if so. * Checks whether the file should be hidden and applies the hidden and not indexed aspects if so.
* *
* @param fileInfo * @param fileInfo
* @return * @return
*/ */
public HiddenFileInfo checkHidden(NodeRef nodeRef) public HiddenFileInfo checkHidden(NodeRef nodeRef, boolean cascade)
{ {
HiddenFileInfo filter = isHidden(nodeRef); HiddenFileInfo filter = onHiddenPath(nodeRef);
if(filter != null) if(filter != null)
{ {
if(!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_HIDDEN))
{
int visibilityMask = filter.getVisibilityMask();
// the file matches a pattern, apply the hidden and aspect control aspects // the file matches a pattern, apply the hidden and aspect control aspects
addHiddenAspect(nodeRef, filter.getVisibilityMask()); addHiddenAspect(nodeRef, visibilityMask);
if(!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_INDEX_CONTROL))
{
addIndexControlAspect(nodeRef); addIndexControlAspect(nodeRef);
} }
if(cascade)
{
applyHidden(nodeRef, visibilityMask);
}
}
}
else else
{ {
// the file does not match the pattern, ensure that the hidden and index control aspects are not present // the file does not match the pattern, ensure that the hidden and index control aspects are not present
@@ -310,6 +434,11 @@ public class HiddenAspect
{ {
removeIndexControlAspect(nodeRef); removeIndexControlAspect(nodeRef);
} }
if(cascade)
{
removeHidden(nodeRef);
}
} }
return filter; return filter;
@@ -445,7 +574,7 @@ public class HiddenAspect
return visibilityMask; return visibilityMask;
} }
boolean isHidden(String path) public boolean isHidden(String path)
{ {
return filter.matcher(path).matches(); return filter.matcher(path).matches();
} }

View File

@@ -5,6 +5,8 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@@ -16,6 +18,8 @@ import javax.transaction.UserTransaction;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.dictionary.DictionaryNamespaceComponent; import org.alfresco.repo.dictionary.DictionaryNamespaceComponent;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.node.NodeDAO.NodeRefQueryCallback;
import org.alfresco.repo.imap.AlfrescoImapFolder; import org.alfresco.repo.imap.AlfrescoImapFolder;
import org.alfresco.repo.imap.AlfrescoImapUser; import org.alfresco.repo.imap.AlfrescoImapUser;
import org.alfresco.repo.imap.ImapService; import org.alfresco.repo.imap.ImapService;
@@ -35,11 +39,14 @@ import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.MutableAuthenticationService; import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.FileFilterMode; import org.alfresco.util.FileFilterMode;
import org.alfresco.util.FileFilterMode.Client; import org.alfresco.util.FileFilterMode.Client;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.alfresco.util.Pair;
import org.alfresco.util.PropertyMap; import org.alfresco.util.PropertyMap;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -56,15 +63,21 @@ public class HiddenAspectTest
private HiddenAspect hiddenAspect; private HiddenAspect hiddenAspect;
private TransactionService transactionService; private TransactionService transactionService;
private NodeDAO nodeDAO;
private NodeService nodeService; private NodeService nodeService;
private FileFolderService fileFolderService; private FileFolderService fileFolderService;
private MutableAuthenticationService authenticationService; private MutableAuthenticationService authenticationService;
private UserTransaction txn; private UserTransaction txn;
private NodeRef rootNodeRef;
private SearchService searchService; private SearchService searchService;
private DictionaryNamespaceComponent namespacePrefixResolver; private DictionaryNamespaceComponent namespacePrefixResolver;
private ImapService imapService; private ImapService imapService;
private PersonService personService; private PersonService personService;
private FilenameFilteringInterceptor interceptor;
private StoreRef storeRef;
private NodeRef rootNodeRef;
private NodeRef topNodeRef;
private final String MAILBOX_NAME_A = "mailbox_a"; private final String MAILBOX_NAME_A = "mailbox_a";
private final String MAILBOX_NAME_B = ".mailbox_a"; private final String MAILBOX_NAME_B = ".mailbox_a";
@@ -80,10 +93,12 @@ public class HiddenAspectTest
fileFolderService = serviceRegistry.getFileFolderService(); fileFolderService = serviceRegistry.getFileFolderService();
authenticationService = (MutableAuthenticationService) ctx.getBean("AuthenticationService"); authenticationService = (MutableAuthenticationService) ctx.getBean("AuthenticationService");
hiddenAspect = (HiddenAspect) ctx.getBean("hiddenAspect"); hiddenAspect = (HiddenAspect) ctx.getBean("hiddenAspect");
searchService = (SearchService) ctx.getBean("searchService"); interceptor = (FilenameFilteringInterceptor) ctx.getBean("filenameFilteringInterceptor");
namespacePrefixResolver = (DictionaryNamespaceComponent) ctx.getBean("namespaceService"); namespacePrefixResolver = (DictionaryNamespaceComponent) ctx.getBean("namespaceService");
imapService = serviceRegistry.getImapService(); imapService = serviceRegistry.getImapService();
personService = serviceRegistry.getPersonService(); personService = serviceRegistry.getPersonService();
searchService = serviceRegistry.getSearchService();
nodeDAO = (NodeDAO)ctx.getBean("nodeDAO");
// start the transaction // start the transaction
txn = transactionService.getUserTransaction(); txn = transactionService.getUserTransaction();
@@ -93,10 +108,16 @@ public class HiddenAspectTest
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
// create a test store // create a test store
StoreRef storeRef = nodeService storeRef = nodeService
.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + System.currentTimeMillis()); .createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + System.currentTimeMillis());
rootNodeRef = nodeService.getRootNode(storeRef); rootNodeRef = nodeService.getRootNode(storeRef);
topNodeRef = nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName(NamespaceService.ALFRESCO_URI, "working root"),
ContentModel.TYPE_FOLDER).getChildRef();
anotherUserName = "user" + System.currentTimeMillis(); anotherUserName = "user" + System.currentTimeMillis();
PropertyMap testUser = new PropertyMap(); PropertyMap testUser = new PropertyMap();
@@ -139,11 +160,11 @@ public class HiddenAspectTest
public void testHiddenFilesEnhancedClient() public void testHiddenFilesEnhancedClient()
{ {
FileFilterMode.setClient(Client.webdav); FileFilterMode.setClient(Client.webdav);
long start = System.currentTimeMillis();
try try
{ {
// check temporary file // check temporary file
NodeRef parent = fileFolderService.create(rootNodeRef, "New Folder", ContentModel.TYPE_FOLDER).getNodeRef(); NodeRef parent = fileFolderService.create(topNodeRef, "New Folder", ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef child = fileFolderService.create(parent, "file.tmp", ContentModel.TYPE_CONTENT).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_TEMPORARY));
assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_HIDDEN));
@@ -151,7 +172,7 @@ long start = System.currentTimeMillis();
assertEquals(1, children.size()); assertEquals(1, children.size());
// check hidden files - should be hidden for an enhanced client // check hidden files - should be hidden for an enhanced client
parent = fileFolderService.create(rootNodeRef, "abc", ContentModel.TYPE_FOLDER).getNodeRef(); parent = fileFolderService.create(topNodeRef, "abc", ContentModel.TYPE_FOLDER).getNodeRef();
child = fileFolderService.create(parent, ".TemporaryItems", ContentModel.TYPE_FOLDER).getNodeRef(); child = fileFolderService.create(parent, ".TemporaryItems", ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef child1 = fileFolderService.create(child, "inTemporaryItems", ContentModel.TYPE_FOLDER).getNodeRef(); NodeRef child1 = fileFolderService.create(child, "inTemporaryItems", ContentModel.TYPE_FOLDER).getNodeRef();
assertTrue(nodeService.hasAspect(child, ContentModel.ASPECT_TEMPORARY)); assertTrue(nodeService.hasAspect(child, ContentModel.ASPECT_TEMPORARY));
@@ -177,7 +198,7 @@ long start = System.currentTimeMillis();
} }
assertEquals(0, children.size()); assertEquals(0, children.size());
parent = fileFolderService.create(rootNodeRef, "Folder 2", ContentModel.TYPE_FOLDER).getNodeRef(); parent = fileFolderService.create(topNodeRef, "Folder 2", ContentModel.TYPE_FOLDER).getNodeRef();
child = fileFolderService.create(parent, "Thumbs.db", ContentModel.TYPE_CONTENT).getNodeRef(); child = fileFolderService.create(parent, "Thumbs.db", ContentModel.TYPE_CONTENT).getNodeRef();
assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_TEMPORARY)); assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_TEMPORARY));
assertTrue(nodeService.hasAspect(child, ContentModel.ASPECT_HIDDEN)); assertTrue(nodeService.hasAspect(child, ContentModel.ASPECT_HIDDEN));
@@ -195,7 +216,7 @@ long start = System.currentTimeMillis();
assertEquals(Visibility.NotVisible, hiddenAspect.getVisibility(Client.webclient, child)); assertEquals(Visibility.NotVisible, hiddenAspect.getVisibility(Client.webclient, child));
// surf-config should not be visible to any client // surf-config should not be visible to any client
NodeRef node = fileFolderService.create(rootNodeRef, "surf-config", ContentModel.TYPE_FOLDER).getNodeRef(); NodeRef node = fileFolderService.create(topNodeRef, "surf-config", ContentModel.TYPE_FOLDER).getNodeRef();
assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName("surf-config"); results = searchForName("surf-config");
@@ -206,7 +227,7 @@ long start = System.currentTimeMillis();
} }
// .DS_Store is a system path and so is visible in nfs and webdav, as a hidden file in cifs and hidden to all other clients // .DS_Store is a system path and so is visible in nfs and webdav, as a hidden file in cifs and hidden to all other clients
node = fileFolderService.create(rootNodeRef, ".DS_Store", ContentModel.TYPE_CONTENT).getNodeRef(); node = fileFolderService.create(topNodeRef, ".DS_Store", ContentModel.TYPE_CONTENT).getNodeRef();
assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName(".DS_Store"); results = searchForName(".DS_Store");
@@ -228,7 +249,7 @@ long start = System.currentTimeMillis();
} }
// Resource fork should not be visible to any client // Resource fork should not be visible to any client
node = fileFolderService.create(rootNodeRef, "._resourceFork", ContentModel.TYPE_FOLDER).getNodeRef(); node = fileFolderService.create(topNodeRef, "._resourceFork", ContentModel.TYPE_FOLDER).getNodeRef();
assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName("._resourceFork"); results = searchForName("._resourceFork");
@@ -237,23 +258,66 @@ long start = System.currentTimeMillis();
{ {
assertEquals(Visibility.NotVisible, hiddenAspect.getVisibility(client, node)); assertEquals(Visibility.NotVisible, hiddenAspect.getVisibility(client, node));
} }
}
finally
{
FileFilterMode.clearClient();
}
}
@Test
public void testImap()
{
FileFilterMode.setClient(Client.webdav);
try
{
// Test that hidden files don't apply to imap service
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
imapService.renameMailbox(user, MAILBOX_NAME_A, MAILBOX_NAME_B);
assertFalse("Can't rename mailbox", checkMailbox(user, MAILBOX_NAME_A));
assertTrue("Can't rename mailbox", checkMailbox(user, MAILBOX_NAME_B));
assertEquals("Can't rename mailbox", 0, numMailboxes(user, MAILBOX_NAME_A));
assertEquals("Can't rename mailbox", 1, numMailboxes(user, MAILBOX_NAME_B));
}
finally
{
FileFilterMode.clearClient();
}
}
@Test
public void testRename()
{
FileFilterMode.setClient(Client.webdav);
try
{
// Test renaming // Test renaming
String nodeName = GUID.generate(); String nodeName = GUID.generate();
node = fileFolderService.create(rootNodeRef, nodeName, ContentModel.TYPE_CONTENT).getNodeRef(); NodeRef node = fileFolderService.create(topNodeRef, nodeName, ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef node1 = fileFolderService.create(node, nodeName + ".1", ContentModel.TYPE_CONTENT).getNodeRef(); NodeRef node11 = fileFolderService.create(node, nodeName + ".11", ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef node2 = fileFolderService.create(node1, nodeName + ".2", ContentModel.TYPE_CONTENT).getNodeRef(); NodeRef node12 = fileFolderService.create(node, nodeName + ".12", ContentModel.TYPE_CONTENT).getNodeRef();
NodeRef node3 = fileFolderService.create(node2, nodeName + ".3", ContentModel.TYPE_CONTENT).getNodeRef(); NodeRef node21 = fileFolderService.create(node11, nodeName + ".21", ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef node22 = fileFolderService.create(node11, nodeName + ".22", ContentModel.TYPE_CONTENT).getNodeRef();
NodeRef node31 = fileFolderService.create(node21, ".31", ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef node41 = fileFolderService.create(node31, nodeName + ".41", ContentModel.TYPE_CONTENT).getNodeRef();
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node1, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(node11, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node1, ContentModel.ASPECT_INDEX_CONTROL)); assertFalse(nodeService.hasAspect(node11, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node2, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(node12, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node2, ContentModel.ASPECT_INDEX_CONTROL)); assertFalse(nodeService.hasAspect(node12, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node3, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(node21, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node3, ContentModel.ASPECT_INDEX_CONTROL)); assertFalse(nodeService.hasAspect(node21, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node22, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node22, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node31, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node31, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node41, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node41, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName(nodeName); ResultSet results = searchForName(nodeName);
assertEquals("", 1, results.length()); assertEquals("", 1, results.length());
try try
@@ -268,8 +332,21 @@ long start = System.currentTimeMillis();
{ {
fail(); fail();
} }
assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertTrue(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node11, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node11, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node12, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node12, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node21, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node21, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node22, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node22, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node31, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node31, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node41, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node41, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName(nodeName); results = searchForName(nodeName);
assertEquals("", 0, results.length()); assertEquals("", 0, results.length());
@@ -289,25 +366,28 @@ long start = System.currentTimeMillis();
{ {
fail(); fail();
} }
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node11, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node11, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node12, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node12, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node21, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node21, ContentModel.ASPECT_INDEX_CONTROL));
assertFalse(nodeService.hasAspect(node22, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node22, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node31, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node31, ContentModel.ASPECT_INDEX_CONTROL));
assertTrue(nodeService.hasAspect(node41, ContentModel.ASPECT_HIDDEN));
assertTrue(nodeService.hasAspect(node41, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName(nodeName); results = searchForName(nodeName);
assertEquals("", 1, results.length()); assertEquals("", 1, results.length());
// Test imap service
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
imapService.renameMailbox(user, MAILBOX_NAME_A, MAILBOX_NAME_B);
assertFalse("Can't rename mailbox", checkMailbox(user, MAILBOX_NAME_A));
assertTrue("Can't rename mailbox", checkMailbox(user, MAILBOX_NAME_B));
assertEquals("Can't rename mailbox", 0, numMailboxes(user, MAILBOX_NAME_A));
assertEquals("Can't rename mailbox", 1, numMailboxes(user, MAILBOX_NAME_B));
} }
finally finally
{ {
FileFilterMode.clearClient(); FileFilterMode.clearClient();
long end = System.currentTimeMillis();
System.out.println((end - start)/1000 + "s");
} }
} }
@@ -319,7 +399,7 @@ long start = System.currentTimeMillis();
try try
{ {
// check temporary file // check temporary file
NodeRef parent = fileFolderService.create(rootNodeRef, "New Folder", ContentModel.TYPE_FOLDER).getNodeRef(); NodeRef parent = fileFolderService.create(topNodeRef, "New Folder", ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef child = fileFolderService.create(parent, "file.tmp", ContentModel.TYPE_CONTENT).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_TEMPORARY));
assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_HIDDEN));
@@ -330,7 +410,7 @@ long start = System.currentTimeMillis();
assertEquals(1, children.size()); assertEquals(1, children.size());
// check hidden files - should not be hidden for a basic client // check hidden files - should not be hidden for a basic client
parent = fileFolderService.create(rootNodeRef, ".TemporaryItems", ContentModel.TYPE_FOLDER).getNodeRef(); parent = fileFolderService.create(topNodeRef, ".TemporaryItems", ContentModel.TYPE_FOLDER).getNodeRef();
child = fileFolderService.create(parent, "inTemporaryItems", ContentModel.TYPE_FOLDER).getNodeRef(); child = fileFolderService.create(parent, "inTemporaryItems", ContentModel.TYPE_FOLDER).getNodeRef();
assertFalse(nodeService.hasAspect(parent, ContentModel.ASPECT_TEMPORARY)); assertFalse(nodeService.hasAspect(parent, ContentModel.ASPECT_TEMPORARY));
assertFalse(nodeService.hasAspect(parent, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(parent, ContentModel.ASPECT_HIDDEN));
@@ -343,7 +423,7 @@ long start = System.currentTimeMillis();
children = fileFolderService.list(parent); children = fileFolderService.list(parent);
assertEquals(1, children.size()); assertEquals(1, children.size());
parent = fileFolderService.create(rootNodeRef, "Folder 2", ContentModel.TYPE_FOLDER).getNodeRef(); parent = fileFolderService.create(topNodeRef, "Folder 2", ContentModel.TYPE_FOLDER).getNodeRef();
child = fileFolderService.create(parent, "Thumbs.db", ContentModel.TYPE_CONTENT).getNodeRef(); child = fileFolderService.create(parent, "Thumbs.db", ContentModel.TYPE_CONTENT).getNodeRef();
assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_TEMPORARY)); assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_TEMPORARY));
assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(child, ContentModel.ASPECT_HIDDEN));
@@ -353,13 +433,13 @@ long start = System.currentTimeMillis();
children = fileFolderService.list(parent); children = fileFolderService.list(parent);
assertEquals(1, children.size()); assertEquals(1, children.size());
NodeRef node = fileFolderService.create(rootNodeRef, "surf-config", ContentModel.TYPE_FOLDER).getNodeRef(); NodeRef node = fileFolderService.create(topNodeRef, "surf-config", ContentModel.TYPE_FOLDER).getNodeRef();
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName("surf-config"); results = searchForName("surf-config");
assertEquals("", 1, results.length()); assertEquals("", 1, results.length());
node = fileFolderService.create(rootNodeRef, ".DS_Store", ContentModel.TYPE_CONTENT).getNodeRef(); node = fileFolderService.create(topNodeRef, ".DS_Store", ContentModel.TYPE_CONTENT).getNodeRef();
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName(".DS_Store"); results = searchForName(".DS_Store");
@@ -369,7 +449,7 @@ long start = System.currentTimeMillis();
assertEquals("Should be visible for client " + client, Visibility.Visible, hiddenAspect.getVisibility(client, node)); assertEquals("Should be visible for client " + client, Visibility.Visible, hiddenAspect.getVisibility(client, node));
} }
node = fileFolderService.create(rootNodeRef, "._resourceFork", ContentModel.TYPE_FOLDER).getNodeRef(); node = fileFolderService.create(topNodeRef, "._resourceFork", ContentModel.TYPE_FOLDER).getNodeRef();
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName("._resourceFork"); results = searchForName("._resourceFork");
@@ -380,7 +460,7 @@ long start = System.currentTimeMillis();
String nodeName = "Node" + System.currentTimeMillis(); String nodeName = "Node" + System.currentTimeMillis();
node = fileFolderService.create(rootNodeRef, nodeName, ContentModel.TYPE_CONTENT).getNodeRef(); node = fileFolderService.create(topNodeRef, nodeName, ContentModel.TYPE_CONTENT).getNodeRef();
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_HIDDEN));
assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL)); assertFalse(nodeService.hasAspect(node, ContentModel.ASPECT_INDEX_CONTROL));
results = searchForName(nodeName); results = searchForName(nodeName);
@@ -437,6 +517,59 @@ long start = System.currentTimeMillis();
} }
} }
@Test
public void testCheckHidden() throws Exception
{
String nodeName = GUID.generate();
interceptor.setEnabled(false);
try
{
// Create some nodes that should be hidden but aren't
NodeRef node = fileFolderService.create(topNodeRef, nodeName, ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef node11 = fileFolderService.create(node, nodeName + ".11", ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef node12 = fileFolderService.create(node, ".12", ContentModel.TYPE_CONTENT).getNodeRef();
NodeRef node21 = fileFolderService.create(node11, nodeName + ".21", ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef node22 = fileFolderService.create(node11, nodeName + ".22", ContentModel.TYPE_CONTENT).getNodeRef();
NodeRef node31 = fileFolderService.create(node21, ".31", ContentModel.TYPE_FOLDER).getNodeRef();
NodeRef node41 = fileFolderService.create(node31, nodeName + ".41", ContentModel.TYPE_CONTENT).getNodeRef();
assertEquals(1, searchForName(".12").length());
assertEquals(1, searchForName(".31").length());
assertEquals(1, searchForName(nodeName + ".41").length());
txn.commit();
}
finally
{
interceptor.setEnabled(true);
}
}
private List<NodeRef> getHiddenNodes(final StoreRef storeRef)
{
final List<NodeRef> nodes = new ArrayList<NodeRef>(20);
NodeRefQueryCallback resultsCallback = new NodeRefQueryCallback()
{
@Override
public boolean handle(Pair<Long, NodeRef> nodePair)
{
if(storeRef == null || nodePair.getSecond().getStoreRef().equals(storeRef))
{
nodes.add(nodePair.getSecond());
}
return true;
}
};
nodeDAO.getNodesWithAspects(Collections.singleton(ContentModel.ASPECT_HIDDEN), 0l, Long.MAX_VALUE, resultsCallback);
return nodes;
}
private int numMailboxes(AlfrescoImapUser user, String mailboxName) private int numMailboxes(AlfrescoImapUser user, String mailboxName)
{ {
int numMailboxes = 0; int numMailboxes = 0;

View File

@@ -10,4 +10,5 @@ public interface HiddenFileInfo
{ {
public int getVisibilityMask(); public int getVisibilityMask();
public String getFilter(); public String getFilter();
public boolean isHidden(String path);
} }