mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-15 15:02:20 +00:00
Merged 5.1.N (5.1.2) to 5.2.N (5.2.1)
125605 rmunteanu: Merged 5.1.1 (5.1.1) to 5.1.N (5.1.2) 125498 slanglois: MNT-16155 Update source headers - remove svn:eol-style property on Java and JSP source files git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@125783 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,415 +1,415 @@
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.model.filefolder.HiddenAspect.Visibility;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
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.FileFilterMode;
|
||||
import org.alfresco.util.FileFilterMode.Client;
|
||||
import org.alfresco.util.FileFilterMode.Mode;
|
||||
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 FileFolderService methods, ensuring system, temporary and hidden files
|
||||
* and paths are marked with the correct aspects.
|
||||
*
|
||||
* @author alex.mukha
|
||||
*/
|
||||
public class FilenameFilteringInterceptor implements MethodInterceptor
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(FilenameFilteringInterceptor.class);
|
||||
|
||||
private static final String XLSX_MIMETYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
|
||||
private static final String MACOS_TEMPORARY_FILE_NAME_PREFIX = "._";
|
||||
private static final Pattern XSL_MACOS_TEMPORARY_FILENAME_FITLER = Pattern.compile("^(\\" + MACOS_TEMPORARY_FILE_NAME_PREFIX + ")?[0-9,a-f]{8}$", Pattern.CASE_INSENSITIVE
|
||||
| Pattern.UNICODE_CASE);
|
||||
|
||||
private NodeService nodeService;
|
||||
private PermissionService permissionService;
|
||||
|
||||
private ContentService contentService;
|
||||
|
||||
private PatternFilter temporaryFiles;
|
||||
private PatternFilter systemPaths;
|
||||
private HiddenAspect hiddenAspect;
|
||||
private boolean enabled = true;
|
||||
|
||||
public FilenameFilteringInterceptor()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of regular expressions that represent patterns of temporary files.
|
||||
*
|
||||
*/
|
||||
public void setTemporaryFiles(PatternFilter temporaryFiles)
|
||||
{
|
||||
this.temporaryFiles = temporaryFiles;
|
||||
}
|
||||
|
||||
public void setHiddenAspect(HiddenAspect hiddenAspect)
|
||||
{
|
||||
this.hiddenAspect = hiddenAspect;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
public Client getClient()
|
||||
{
|
||||
return FileFilterMode.getClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeService the service to use to apply the <b>sys:temporary</b> aspect
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setPermissionService(PermissionService permissionService)
|
||||
{
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
public void setContentService(ContentService contentService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
}
|
||||
|
||||
public ContentService getContentService()
|
||||
{
|
||||
return contentService;
|
||||
}
|
||||
|
||||
private void checkTemporaryAspect(boolean isTemporary, FileInfo fileInfo)
|
||||
{
|
||||
checkTemporaryAspect(isTemporary, fileInfo.getNodeRef());
|
||||
}
|
||||
|
||||
private void checkTemporaryAspect(boolean isTemporary, NodeRef nodeRef)
|
||||
{
|
||||
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: " + nodeRef);
|
||||
}
|
||||
}
|
||||
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: " + nodeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<Element> 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;
|
||||
}
|
||||
|
||||
private int getSystemFileVisibilityMask()
|
||||
{
|
||||
int mask = 0;
|
||||
mask |= hiddenAspect.getClientVisibilityMask(Client.cifs, Visibility.HiddenAttribute);
|
||||
mask |= hiddenAspect.getClientVisibilityMask(Client.webdav, Visibility.Visible);
|
||||
mask |= hiddenAspect.getClientVisibilityMask(Client.nfs, Visibility.Visible);
|
||||
mask |= hiddenAspect.getClientVisibilityMask(Client.ftp, Visibility.Visible);
|
||||
return mask;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
// 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;
|
||||
boolean isTmp = isTemporaryObject(filename, sourceInfo.getNodeRef());
|
||||
checkTemporaryAspect(isTmp, sourceInfo);
|
||||
boolean isHidden = hiddenAspect.checkHidden(fileInfo, false, false);
|
||||
if(isHidden && fileInfo instanceof FileInfoImpl)
|
||||
{
|
||||
((FileInfoImpl)fileInfo).setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
{
|
||||
ret = invocation.proceed();
|
||||
}
|
||||
|
||||
// done
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether specified <code>name</code> matches any pattern of temporary file names.
|
||||
* <br>Also it checks special case of new XLS document creation in MacOS:
|
||||
* <ul>
|
||||
* <li>its name doesn’t have extension (on MacOS, but it has ‘.tmp’ extension on Windows);
|
||||
* <li>length of its name equals to 8;
|
||||
* <li>its name contains only hexadecimal digits (0-9, A-F);
|
||||
* <li>it has Mimetype equal to ‘application/vnd.openxmlformats-officedocument.spreadsheetml.sheet’.
|
||||
* </ul>
|
||||
*
|
||||
* @param name - {@link String} value which contains name of node
|
||||
* @param nodeRef - {@link NodeRef} instance of the node
|
||||
* @return {@link boolean} value. <code>true</code> if <code>name</code> is name of temporary object.
|
||||
*/
|
||||
private boolean isTemporaryObject(String name, NodeRef nodeRef)
|
||||
{
|
||||
boolean isFiltered = temporaryFiles.isFiltered(name);
|
||||
if (isFiltered)
|
||||
{
|
||||
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))
|
||||
{
|
||||
ContentReader contentReader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
|
||||
|
||||
if (null != contentReader)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.model.filefolder.HiddenAspect.Visibility;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
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.FileFilterMode;
|
||||
import org.alfresco.util.FileFilterMode.Client;
|
||||
import org.alfresco.util.FileFilterMode.Mode;
|
||||
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 FileFolderService methods, ensuring system, temporary and hidden files
|
||||
* and paths are marked with the correct aspects.
|
||||
*
|
||||
* @author alex.mukha
|
||||
*/
|
||||
public class FilenameFilteringInterceptor implements MethodInterceptor
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(FilenameFilteringInterceptor.class);
|
||||
|
||||
private static final String XLSX_MIMETYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
|
||||
private static final String MACOS_TEMPORARY_FILE_NAME_PREFIX = "._";
|
||||
private static final Pattern XSL_MACOS_TEMPORARY_FILENAME_FITLER = Pattern.compile("^(\\" + MACOS_TEMPORARY_FILE_NAME_PREFIX + ")?[0-9,a-f]{8}$", Pattern.CASE_INSENSITIVE
|
||||
| Pattern.UNICODE_CASE);
|
||||
|
||||
private NodeService nodeService;
|
||||
private PermissionService permissionService;
|
||||
|
||||
private ContentService contentService;
|
||||
|
||||
private PatternFilter temporaryFiles;
|
||||
private PatternFilter systemPaths;
|
||||
private HiddenAspect hiddenAspect;
|
||||
private boolean enabled = true;
|
||||
|
||||
public FilenameFilteringInterceptor()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of regular expressions that represent patterns of temporary files.
|
||||
*
|
||||
*/
|
||||
public void setTemporaryFiles(PatternFilter temporaryFiles)
|
||||
{
|
||||
this.temporaryFiles = temporaryFiles;
|
||||
}
|
||||
|
||||
public void setHiddenAspect(HiddenAspect hiddenAspect)
|
||||
{
|
||||
this.hiddenAspect = hiddenAspect;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
public Client getClient()
|
||||
{
|
||||
return FileFilterMode.getClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nodeService the service to use to apply the <b>sys:temporary</b> aspect
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setPermissionService(PermissionService permissionService)
|
||||
{
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
public void setContentService(ContentService contentService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
}
|
||||
|
||||
public ContentService getContentService()
|
||||
{
|
||||
return contentService;
|
||||
}
|
||||
|
||||
private void checkTemporaryAspect(boolean isTemporary, FileInfo fileInfo)
|
||||
{
|
||||
checkTemporaryAspect(isTemporary, fileInfo.getNodeRef());
|
||||
}
|
||||
|
||||
private void checkTemporaryAspect(boolean isTemporary, NodeRef nodeRef)
|
||||
{
|
||||
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: " + nodeRef);
|
||||
}
|
||||
}
|
||||
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: " + nodeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<Element> 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;
|
||||
}
|
||||
|
||||
private int getSystemFileVisibilityMask()
|
||||
{
|
||||
int mask = 0;
|
||||
mask |= hiddenAspect.getClientVisibilityMask(Client.cifs, Visibility.HiddenAttribute);
|
||||
mask |= hiddenAspect.getClientVisibilityMask(Client.webdav, Visibility.Visible);
|
||||
mask |= hiddenAspect.getClientVisibilityMask(Client.nfs, Visibility.Visible);
|
||||
mask |= hiddenAspect.getClientVisibilityMask(Client.ftp, Visibility.Visible);
|
||||
return mask;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
// 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;
|
||||
boolean isTmp = isTemporaryObject(filename, sourceInfo.getNodeRef());
|
||||
checkTemporaryAspect(isTmp, sourceInfo);
|
||||
boolean isHidden = hiddenAspect.checkHidden(fileInfo, false, false);
|
||||
if(isHidden && fileInfo instanceof FileInfoImpl)
|
||||
{
|
||||
((FileInfoImpl)fileInfo).setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
{
|
||||
ret = invocation.proceed();
|
||||
}
|
||||
|
||||
// done
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether specified <code>name</code> matches any pattern of temporary file names.
|
||||
* <br>Also it checks special case of new XLS document creation in MacOS:
|
||||
* <ul>
|
||||
* <li>its name doesn’t have extension (on MacOS, but it has ‘.tmp’ extension on Windows);
|
||||
* <li>length of its name equals to 8;
|
||||
* <li>its name contains only hexadecimal digits (0-9, A-F);
|
||||
* <li>it has Mimetype equal to ‘application/vnd.openxmlformats-officedocument.spreadsheetml.sheet’.
|
||||
* </ul>
|
||||
*
|
||||
* @param name - {@link String} value which contains name of node
|
||||
* @param nodeRef - {@link NodeRef} instance of the node
|
||||
* @return {@link boolean} value. <code>true</code> if <code>name</code> is name of temporary object.
|
||||
*/
|
||||
private boolean isTemporaryObject(String name, NodeRef nodeRef)
|
||||
{
|
||||
boolean isFiltered = temporaryFiles.isFiltered(name);
|
||||
if (isFiltered)
|
||||
{
|
||||
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))
|
||||
{
|
||||
ContentReader contentReader = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
|
||||
|
||||
if (null != contentReader)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,183 +1,183 @@
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.query.CannedQueryParameters;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.domain.node.NodePropertyHelper;
|
||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||
import org.alfresco.repo.domain.query.CannedQueryDAO;
|
||||
import org.alfresco.repo.model.filefolder.HiddenAspect.Visibility;
|
||||
import org.alfresco.repo.node.getchildren.FilterProp;
|
||||
import org.alfresco.repo.node.getchildren.GetChildrenCannedQueryParams;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityBean;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.FileFilterMode;
|
||||
import org.alfresco.util.FileFilterMode.Client;
|
||||
|
||||
/**
|
||||
* GetChidren canned query for files and folders.
|
||||
*
|
||||
* To get paged list of files and folders of a parent folder filtered by child type.
|
||||
* Also optionally filtered and/or sorted by one or more properties (up to three).
|
||||
*
|
||||
* This is the same as the nodes getchildren canned query, except it takes into account hidden files and folders (with respect to client visibility)
|
||||
* and other aspect(s) to ignore - eg. optionally "cm:checkedOut" in case of Share DocLib.
|
||||
*
|
||||
* @since 4.1.1
|
||||
* @author steveglover, janv
|
||||
*
|
||||
*/
|
||||
public class GetChildrenCannedQuery extends org.alfresco.repo.node.getchildren.GetChildrenCannedQuery
|
||||
{
|
||||
private HiddenAspect hiddenAspect;
|
||||
private DictionaryService dictionaryService;
|
||||
private NodeService nodeService;
|
||||
private Set<QName> ignoreAspectQNames;
|
||||
|
||||
public GetChildrenCannedQuery(
|
||||
NodeDAO nodeDAO,
|
||||
QNameDAO qnameDAO,
|
||||
CannedQueryDAO cannedQueryDAO,
|
||||
NodePropertyHelper nodePropertyHelper,
|
||||
TenantService tenantService,
|
||||
NodeService nodeService,
|
||||
MethodSecurityBean<NodeRef> methodSecurity,
|
||||
CannedQueryParameters params,
|
||||
HiddenAspect hiddenAspect,
|
||||
DictionaryService dictionaryService,
|
||||
Set<QName> ignoreAspectQNames)
|
||||
{
|
||||
super(nodeDAO, qnameDAO, cannedQueryDAO, nodePropertyHelper, tenantService, nodeService, methodSecurity, params);
|
||||
|
||||
this.hiddenAspect = hiddenAspect;
|
||||
this.dictionaryService = dictionaryService;
|
||||
|
||||
this.nodeService = nodeService;
|
||||
this.ignoreAspectQNames = ignoreAspectQNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UnsortedChildQueryCallback getUnsortedChildQueryCallback(final List<NodeRef> rawResult, final int requestedCount, GetChildrenCannedQueryParams paramBean)
|
||||
{
|
||||
Set<QName> inclusiveAspects = paramBean.getInclusiveAspects();
|
||||
Set<QName> exclusiveAspects = paramBean.getExclusiveAspects();
|
||||
|
||||
UnsortedChildQueryCallback callback = new FileFolderUnsortedChildQueryCallback(rawResult, requestedCount, inclusiveAspects, exclusiveAspects);
|
||||
return callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FilterSortChildQueryCallback getFilterSortChildQuery(final List<FilterSortNode> children, final List<FilterProp> filterProps, GetChildrenCannedQueryParams paramBean)
|
||||
{
|
||||
FilterSortChildQueryCallback callback = new FileFolderFilterSortChildQueryCallback(children, filterProps);
|
||||
return callback;
|
||||
}
|
||||
|
||||
private class FileFolderFilterSortChildQueryCallback extends DefaultFilterSortChildQueryCallback
|
||||
{
|
||||
private Map<QName, Boolean> isTypeFolderMap = new HashMap<QName, Boolean>(10);
|
||||
|
||||
public FileFolderFilterSortChildQueryCallback(List<FilterSortNode> children, List<FilterProp> filterProps)
|
||||
{
|
||||
super(children, filterProps);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean include(FilterSortNode node)
|
||||
{
|
||||
boolean ret = super.include(node);
|
||||
return ret && includeImpl(ret, node.getNodeRef());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(FilterSortNode node)
|
||||
{
|
||||
super.handle(node);
|
||||
|
||||
Map<QName, Serializable> propVals = node.getPropVals();
|
||||
QName nodeTypeQName = (QName)propVals.get(GetChildrenCannedQuery.SORT_QNAME_NODE_TYPE);
|
||||
|
||||
if (nodeTypeQName != null)
|
||||
{
|
||||
// ALF-13968
|
||||
Boolean isFolder = isTypeFolderMap.get(nodeTypeQName);
|
||||
if (isFolder == null)
|
||||
{
|
||||
isFolder = dictionaryService.isSubClass(nodeTypeQName, ContentModel.TYPE_FOLDER);
|
||||
isTypeFolderMap.put(nodeTypeQName, isFolder);
|
||||
}
|
||||
|
||||
propVals.put(GetChildrenCannedQuery.SORT_QNAME_NODE_IS_FOLDER, isFolder);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class FileFolderUnsortedChildQueryCallback extends DefaultUnsortedChildQueryCallback
|
||||
{
|
||||
public FileFolderUnsortedChildQueryCallback(List<NodeRef> rawResult,int requestedCount, Set<QName> inclusiveAspects, Set<QName> exclusiveAspects)
|
||||
{
|
||||
super(rawResult, requestedCount, inclusiveAspects, exclusiveAspects);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean include(NodeRef nodeRef)
|
||||
{
|
||||
boolean ret = super.include(nodeRef);
|
||||
|
||||
return ret && includeImpl(ret, nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean includeImpl(boolean ret, NodeRef nodeRef)
|
||||
{
|
||||
// only visible files are returned, relative to the client type.
|
||||
try
|
||||
{
|
||||
if (!nodeService.exists(nodeRef))
|
||||
{
|
||||
// Node has disappeared
|
||||
return ret;
|
||||
}
|
||||
|
||||
final Client client = FileFilterMode.getClient();
|
||||
boolean notHidden = hiddenAspect.getVisibility(client, nodeRef) != Visibility.NotVisible;
|
||||
|
||||
boolean notIgnore = true;
|
||||
if (ignoreAspectQNames != null)
|
||||
{
|
||||
if (ignoreAspectQNames.size() > 1)
|
||||
{
|
||||
Set<QName> nodeAspects = nodeService.getAspects(nodeRef);
|
||||
notIgnore = (! nodeAspects.removeAll(ignoreAspectQNames));
|
||||
}
|
||||
else if (ignoreAspectQNames.size() == 1)
|
||||
{
|
||||
if (nodeService.hasAspect(nodeRef, ignoreAspectQNames.iterator().next()))
|
||||
{
|
||||
notIgnore = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret && notHidden && notIgnore;
|
||||
}
|
||||
catch (AccessDeniedException e)
|
||||
{
|
||||
// user may not have permission to determine the visibility of the node
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.query.CannedQueryParameters;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.domain.node.NodePropertyHelper;
|
||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||
import org.alfresco.repo.domain.query.CannedQueryDAO;
|
||||
import org.alfresco.repo.model.filefolder.HiddenAspect.Visibility;
|
||||
import org.alfresco.repo.node.getchildren.FilterProp;
|
||||
import org.alfresco.repo.node.getchildren.GetChildrenCannedQueryParams;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityBean;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.FileFilterMode;
|
||||
import org.alfresco.util.FileFilterMode.Client;
|
||||
|
||||
/**
|
||||
* GetChidren canned query for files and folders.
|
||||
*
|
||||
* To get paged list of files and folders of a parent folder filtered by child type.
|
||||
* Also optionally filtered and/or sorted by one or more properties (up to three).
|
||||
*
|
||||
* This is the same as the nodes getchildren canned query, except it takes into account hidden files and folders (with respect to client visibility)
|
||||
* and other aspect(s) to ignore - eg. optionally "cm:checkedOut" in case of Share DocLib.
|
||||
*
|
||||
* @since 4.1.1
|
||||
* @author steveglover, janv
|
||||
*
|
||||
*/
|
||||
public class GetChildrenCannedQuery extends org.alfresco.repo.node.getchildren.GetChildrenCannedQuery
|
||||
{
|
||||
private HiddenAspect hiddenAspect;
|
||||
private DictionaryService dictionaryService;
|
||||
private NodeService nodeService;
|
||||
private Set<QName> ignoreAspectQNames;
|
||||
|
||||
public GetChildrenCannedQuery(
|
||||
NodeDAO nodeDAO,
|
||||
QNameDAO qnameDAO,
|
||||
CannedQueryDAO cannedQueryDAO,
|
||||
NodePropertyHelper nodePropertyHelper,
|
||||
TenantService tenantService,
|
||||
NodeService nodeService,
|
||||
MethodSecurityBean<NodeRef> methodSecurity,
|
||||
CannedQueryParameters params,
|
||||
HiddenAspect hiddenAspect,
|
||||
DictionaryService dictionaryService,
|
||||
Set<QName> ignoreAspectQNames)
|
||||
{
|
||||
super(nodeDAO, qnameDAO, cannedQueryDAO, nodePropertyHelper, tenantService, nodeService, methodSecurity, params);
|
||||
|
||||
this.hiddenAspect = hiddenAspect;
|
||||
this.dictionaryService = dictionaryService;
|
||||
|
||||
this.nodeService = nodeService;
|
||||
this.ignoreAspectQNames = ignoreAspectQNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UnsortedChildQueryCallback getUnsortedChildQueryCallback(final List<NodeRef> rawResult, final int requestedCount, GetChildrenCannedQueryParams paramBean)
|
||||
{
|
||||
Set<QName> inclusiveAspects = paramBean.getInclusiveAspects();
|
||||
Set<QName> exclusiveAspects = paramBean.getExclusiveAspects();
|
||||
|
||||
UnsortedChildQueryCallback callback = new FileFolderUnsortedChildQueryCallback(rawResult, requestedCount, inclusiveAspects, exclusiveAspects);
|
||||
return callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FilterSortChildQueryCallback getFilterSortChildQuery(final List<FilterSortNode> children, final List<FilterProp> filterProps, GetChildrenCannedQueryParams paramBean)
|
||||
{
|
||||
FilterSortChildQueryCallback callback = new FileFolderFilterSortChildQueryCallback(children, filterProps);
|
||||
return callback;
|
||||
}
|
||||
|
||||
private class FileFolderFilterSortChildQueryCallback extends DefaultFilterSortChildQueryCallback
|
||||
{
|
||||
private Map<QName, Boolean> isTypeFolderMap = new HashMap<QName, Boolean>(10);
|
||||
|
||||
public FileFolderFilterSortChildQueryCallback(List<FilterSortNode> children, List<FilterProp> filterProps)
|
||||
{
|
||||
super(children, filterProps);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean include(FilterSortNode node)
|
||||
{
|
||||
boolean ret = super.include(node);
|
||||
return ret && includeImpl(ret, node.getNodeRef());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(FilterSortNode node)
|
||||
{
|
||||
super.handle(node);
|
||||
|
||||
Map<QName, Serializable> propVals = node.getPropVals();
|
||||
QName nodeTypeQName = (QName)propVals.get(GetChildrenCannedQuery.SORT_QNAME_NODE_TYPE);
|
||||
|
||||
if (nodeTypeQName != null)
|
||||
{
|
||||
// ALF-13968
|
||||
Boolean isFolder = isTypeFolderMap.get(nodeTypeQName);
|
||||
if (isFolder == null)
|
||||
{
|
||||
isFolder = dictionaryService.isSubClass(nodeTypeQName, ContentModel.TYPE_FOLDER);
|
||||
isTypeFolderMap.put(nodeTypeQName, isFolder);
|
||||
}
|
||||
|
||||
propVals.put(GetChildrenCannedQuery.SORT_QNAME_NODE_IS_FOLDER, isFolder);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class FileFolderUnsortedChildQueryCallback extends DefaultUnsortedChildQueryCallback
|
||||
{
|
||||
public FileFolderUnsortedChildQueryCallback(List<NodeRef> rawResult,int requestedCount, Set<QName> inclusiveAspects, Set<QName> exclusiveAspects)
|
||||
{
|
||||
super(rawResult, requestedCount, inclusiveAspects, exclusiveAspects);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean include(NodeRef nodeRef)
|
||||
{
|
||||
boolean ret = super.include(nodeRef);
|
||||
|
||||
return ret && includeImpl(ret, nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean includeImpl(boolean ret, NodeRef nodeRef)
|
||||
{
|
||||
// only visible files are returned, relative to the client type.
|
||||
try
|
||||
{
|
||||
if (!nodeService.exists(nodeRef))
|
||||
{
|
||||
// Node has disappeared
|
||||
return ret;
|
||||
}
|
||||
|
||||
final Client client = FileFilterMode.getClient();
|
||||
boolean notHidden = hiddenAspect.getVisibility(client, nodeRef) != Visibility.NotVisible;
|
||||
|
||||
boolean notIgnore = true;
|
||||
if (ignoreAspectQNames != null)
|
||||
{
|
||||
if (ignoreAspectQNames.size() > 1)
|
||||
{
|
||||
Set<QName> nodeAspects = nodeService.getAspects(nodeRef);
|
||||
notIgnore = (! nodeAspects.removeAll(ignoreAspectQNames));
|
||||
}
|
||||
else if (ignoreAspectQNames.size() == 1)
|
||||
{
|
||||
if (nodeService.hasAspect(nodeRef, ignoreAspectQNames.iterator().next()))
|
||||
{
|
||||
notIgnore = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret && notHidden && notIgnore;
|
||||
}
|
||||
catch (AccessDeniedException e)
|
||||
{
|
||||
// user may not have permission to determine the visibility of the node
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,46 +1,46 @@
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.query.CannedQuery;
|
||||
import org.alfresco.query.CannedQueryParameters;
|
||||
import org.alfresco.query.PagingRequest;
|
||||
import org.alfresco.repo.domain.node.NodePropertyHelper;
|
||||
import org.alfresco.repo.node.getchildren.FilterProp;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* GetChidren canned query factory for files and folders.
|
||||
*
|
||||
* @since 4.1.1
|
||||
* @author steveglover, janv
|
||||
*
|
||||
*/
|
||||
public class GetChildrenCannedQueryFactory extends org.alfresco.repo.node.getchildren.GetChildrenCannedQueryFactory
|
||||
{
|
||||
private HiddenAspect hiddenAspect;
|
||||
private Set<QName> ignoreAspectQNames;
|
||||
|
||||
public void setHiddenAspect(HiddenAspect hiddenAspect)
|
||||
{
|
||||
this.hiddenAspect = hiddenAspect;
|
||||
}
|
||||
|
||||
public CannedQuery<NodeRef> getCannedQuery(NodeRef parentRef, String pattern, Set<QName> assocTypeQNames, Set<QName> childTypeQNames, Set<QName> ignoreAspectQNames, List<FilterProp> filterProps, List<Pair<QName, Boolean>> sortProps, PagingRequest pagingRequest)
|
||||
{
|
||||
this.ignoreAspectQNames = ignoreAspectQNames;
|
||||
|
||||
return super.getCannedQuery(parentRef, pattern, assocTypeQNames, childTypeQNames, filterProps, sortProps, pagingRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CannedQuery<NodeRef> getCannedQuery(CannedQueryParameters parameters)
|
||||
{
|
||||
NodePropertyHelper nodePropertyHelper = new NodePropertyHelper(dictionaryService, qnameDAO, localeDAO, contentDataDAO);
|
||||
|
||||
return (CannedQuery<NodeRef>) new GetChildrenCannedQuery(nodeDAO, qnameDAO, cannedQueryDAO, nodePropertyHelper, tenantService, nodeService, methodSecurity, parameters, hiddenAspect, dictionaryService, ignoreAspectQNames);
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.query.CannedQuery;
|
||||
import org.alfresco.query.CannedQueryParameters;
|
||||
import org.alfresco.query.PagingRequest;
|
||||
import org.alfresco.repo.domain.node.NodePropertyHelper;
|
||||
import org.alfresco.repo.node.getchildren.FilterProp;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* GetChidren canned query factory for files and folders.
|
||||
*
|
||||
* @since 4.1.1
|
||||
* @author steveglover, janv
|
||||
*
|
||||
*/
|
||||
public class GetChildrenCannedQueryFactory extends org.alfresco.repo.node.getchildren.GetChildrenCannedQueryFactory
|
||||
{
|
||||
private HiddenAspect hiddenAspect;
|
||||
private Set<QName> ignoreAspectQNames;
|
||||
|
||||
public void setHiddenAspect(HiddenAspect hiddenAspect)
|
||||
{
|
||||
this.hiddenAspect = hiddenAspect;
|
||||
}
|
||||
|
||||
public CannedQuery<NodeRef> getCannedQuery(NodeRef parentRef, String pattern, Set<QName> assocTypeQNames, Set<QName> childTypeQNames, Set<QName> ignoreAspectQNames, List<FilterProp> filterProps, List<Pair<QName, Boolean>> sortProps, PagingRequest pagingRequest)
|
||||
{
|
||||
this.ignoreAspectQNames = ignoreAspectQNames;
|
||||
|
||||
return super.getCannedQuery(parentRef, pattern, assocTypeQNames, childTypeQNames, filterProps, sortProps, pagingRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CannedQuery<NodeRef> getCannedQuery(CannedQueryParameters parameters)
|
||||
{
|
||||
NodePropertyHelper nodePropertyHelper = new NodePropertyHelper(dictionaryService, qnameDAO, localeDAO, contentDataDAO);
|
||||
|
||||
return (CannedQuery<NodeRef>) new GetChildrenCannedQuery(nodeDAO, qnameDAO, cannedQueryDAO, nodePropertyHelper, tenantService, nodeService, methodSecurity, parameters, hiddenAspect, dictionaryService, ignoreAspectQNames);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,100 +1,100 @@
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* Spring bean defining a hidden node filter.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
*/
|
||||
public class HiddenFileFilter implements InitializingBean
|
||||
{
|
||||
private String filter;
|
||||
private String visibility;
|
||||
private String hiddenAttribute;
|
||||
private boolean cascadeHiddenAspect = true;
|
||||
private boolean cascadeIndexControlAspect = true;
|
||||
private boolean cmisDisableHideConfig;
|
||||
|
||||
public HiddenFileFilter()
|
||||
{
|
||||
}
|
||||
|
||||
public void setFilter(String filter)
|
||||
{
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public void setVisibility(String visibility)
|
||||
{
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
public String getFilter()
|
||||
{
|
||||
return filter;
|
||||
}
|
||||
|
||||
public String getVisibility()
|
||||
{
|
||||
return visibility;
|
||||
}
|
||||
|
||||
public String getHiddenAttribute()
|
||||
{
|
||||
return hiddenAttribute;
|
||||
}
|
||||
|
||||
public void setHiddenAttribute(String hiddenAttribute)
|
||||
{
|
||||
this.hiddenAttribute = hiddenAttribute;
|
||||
}
|
||||
|
||||
public void setCascadeHiddenAspect(boolean cascadeHiddenAspect)
|
||||
{
|
||||
this.cascadeHiddenAspect = cascadeHiddenAspect;
|
||||
}
|
||||
|
||||
public boolean cascadeHiddenAspect()
|
||||
{
|
||||
return cascadeHiddenAspect;
|
||||
}
|
||||
|
||||
public void setCascadeIndexControlAspect(boolean cascadeIndexControlAspect)
|
||||
{
|
||||
this.cascadeIndexControlAspect = cascadeIndexControlAspect;
|
||||
}
|
||||
|
||||
public boolean cascadeIndexControlAspect()
|
||||
{
|
||||
return cascadeIndexControlAspect;
|
||||
}
|
||||
|
||||
public void setCmisDisableHideConfig(boolean cmisDisableHideConfig)
|
||||
{
|
||||
this.cmisDisableHideConfig = cmisDisableHideConfig;
|
||||
}
|
||||
|
||||
public boolean isCmisDisableHideConfig()
|
||||
{
|
||||
return cmisDisableHideConfig;
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
PropertyCheck.mandatory(this, "filter", filter);
|
||||
if(visibility == null)
|
||||
{
|
||||
visibility = "";
|
||||
}
|
||||
if(hiddenAttribute == null)
|
||||
{
|
||||
hiddenAttribute = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* Spring bean defining a hidden node filter.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
*/
|
||||
public class HiddenFileFilter implements InitializingBean
|
||||
{
|
||||
private String filter;
|
||||
private String visibility;
|
||||
private String hiddenAttribute;
|
||||
private boolean cascadeHiddenAspect = true;
|
||||
private boolean cascadeIndexControlAspect = true;
|
||||
private boolean cmisDisableHideConfig;
|
||||
|
||||
public HiddenFileFilter()
|
||||
{
|
||||
}
|
||||
|
||||
public void setFilter(String filter)
|
||||
{
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public void setVisibility(String visibility)
|
||||
{
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
public String getFilter()
|
||||
{
|
||||
return filter;
|
||||
}
|
||||
|
||||
public String getVisibility()
|
||||
{
|
||||
return visibility;
|
||||
}
|
||||
|
||||
public String getHiddenAttribute()
|
||||
{
|
||||
return hiddenAttribute;
|
||||
}
|
||||
|
||||
public void setHiddenAttribute(String hiddenAttribute)
|
||||
{
|
||||
this.hiddenAttribute = hiddenAttribute;
|
||||
}
|
||||
|
||||
public void setCascadeHiddenAspect(boolean cascadeHiddenAspect)
|
||||
{
|
||||
this.cascadeHiddenAspect = cascadeHiddenAspect;
|
||||
}
|
||||
|
||||
public boolean cascadeHiddenAspect()
|
||||
{
|
||||
return cascadeHiddenAspect;
|
||||
}
|
||||
|
||||
public void setCascadeIndexControlAspect(boolean cascadeIndexControlAspect)
|
||||
{
|
||||
this.cascadeIndexControlAspect = cascadeIndexControlAspect;
|
||||
}
|
||||
|
||||
public boolean cascadeIndexControlAspect()
|
||||
{
|
||||
return cascadeIndexControlAspect;
|
||||
}
|
||||
|
||||
public void setCmisDisableHideConfig(boolean cmisDisableHideConfig)
|
||||
{
|
||||
this.cmisDisableHideConfig = cmisDisableHideConfig;
|
||||
}
|
||||
|
||||
public boolean isCmisDisableHideConfig()
|
||||
{
|
||||
return cmisDisableHideConfig;
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
PropertyCheck.mandatory(this, "filter", filter);
|
||||
if(visibility == null)
|
||||
{
|
||||
visibility = "";
|
||||
}
|
||||
if(hiddenAttribute == null)
|
||||
{
|
||||
hiddenAttribute = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,17 +1,17 @@
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
/**
|
||||
* Represents hidden file information, including the filter (regular expression) and the visibility mask.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
*/
|
||||
public interface HiddenFileInfo
|
||||
{
|
||||
public boolean cascadeHiddenAspect();
|
||||
public boolean cascadeIndexControlAspect();
|
||||
public boolean isClientControlled();
|
||||
public int getVisibilityMask();
|
||||
public String getFilter();
|
||||
public boolean isHidden(String path);
|
||||
}
|
||||
package org.alfresco.repo.model.filefolder;
|
||||
|
||||
/**
|
||||
* Represents hidden file information, including the filter (regular expression) and the visibility mask.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
*/
|
||||
public interface HiddenFileInfo
|
||||
{
|
||||
public boolean cascadeHiddenAspect();
|
||||
public boolean cascadeIndexControlAspect();
|
||||
public boolean isClientControlled();
|
||||
public int getVisibilityMask();
|
||||
public String getFilter();
|
||||
public boolean isHidden(String path);
|
||||
}
|
||||
|
Reference in New Issue
Block a user