mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged HEAD-QA to HEAD (4.2) (including moving test classes into separate folders)
51903 to 54309 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@54310 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -32,14 +32,27 @@ public interface AlfrescoImapConst
|
||||
{
|
||||
/**
|
||||
* Defines {@link AlfrescoImapFolder} view mode as virtual mode. Used for IMAP Virtualised View.
|
||||
* <p>
|
||||
* In the virtual mode alfresco nodes of cm:content are shown regardless of whether they are IMAP messages.
|
||||
* <p>
|
||||
* A template is used to generate a "virtual" email message from a content item that is not an email message.
|
||||
* <p>
|
||||
* Only nodes from IMAP favourite sites are shown, non favourite sites are not shown.
|
||||
*/
|
||||
VIRTUAL,
|
||||
/**
|
||||
* Defines {@link AlfrescoImapFolder} view mode as mixed mode. Used for IMAP Mixed View.
|
||||
* <p>
|
||||
* In mixed mode both IMAP messages and Alfresco nodes of other types are shown.
|
||||
* Only nodes from IMAP favourite sites are shown, non favourite sites are not shown.
|
||||
*
|
||||
*/
|
||||
MIXED,
|
||||
/**
|
||||
* Defines {@link AlfrescoImapFolder} view mode as archive mode. Used for Email Archive View.
|
||||
* <p>
|
||||
* In archive mode only IMAP messages are shown. Alfresco nodes of other types are not shown.
|
||||
* And no nodes within sites (favourite or otherwise) are shown.
|
||||
*/
|
||||
ARCHIVE
|
||||
}
|
||||
|
@@ -100,6 +100,7 @@ public class AlfrescoImapServer extends AbstractLifecycleBean
|
||||
private int port = 143;
|
||||
private int securePort = 993;
|
||||
private boolean imapsEnabled = false;
|
||||
private boolean imapEnabled = true;
|
||||
|
||||
private String host = "0.0.0.0";
|
||||
|
||||
@@ -198,12 +199,15 @@ public class AlfrescoImapServer extends AbstractLifecycleBean
|
||||
}
|
||||
};
|
||||
|
||||
serverImpl = new ImapServer(new ServerSetup(port, host, ServerSetup.PROTOCOL_IMAP), imapManagers);
|
||||
serverImpl.startService(null);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
if(isImapEnabled())
|
||||
{
|
||||
logger.info("IMAP service started on host:port " + host + ":" + this.port);
|
||||
serverImpl = new ImapServer(new ServerSetup(port, host, ServerSetup.PROTOCOL_IMAP), imapManagers);
|
||||
serverImpl.startService(null);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.info("IMAP service started on host:port " + host + ":" + this.port);
|
||||
}
|
||||
}
|
||||
if(isImapsEnabled())
|
||||
{
|
||||
@@ -255,4 +259,14 @@ public class AlfrescoImapServer extends AbstractLifecycleBean
|
||||
{
|
||||
return imapsEnabled;
|
||||
}
|
||||
|
||||
public void setImapEnabled(boolean imapEnabled)
|
||||
{
|
||||
this.imapEnabled = imapEnabled;
|
||||
}
|
||||
|
||||
public boolean isImapEnabled()
|
||||
{
|
||||
return imapEnabled;
|
||||
}
|
||||
}
|
||||
|
@@ -18,9 +18,11 @@
|
||||
*/
|
||||
package org.alfresco.repo.imap;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Multipart;
|
||||
@@ -32,16 +34,20 @@ import javax.mail.internet.MimeUtility;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ImapModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.util.config.RepositoryFolderConfigBean;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.poi.hmef.HMEFMessage;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
@@ -76,6 +82,7 @@ public class AttachmentsExtractor
|
||||
private RepositoryFolderConfigBean attachmentsFolder;
|
||||
private NodeRef attachmentsFolderRef;
|
||||
private AttachmentsExtractorMode attachmentsExtractorMode;
|
||||
private MimetypeService mimetypeService;
|
||||
|
||||
public void setFileFolderService(FileFolderService fileFolderService)
|
||||
{
|
||||
@@ -107,15 +114,32 @@ public class AttachmentsExtractor
|
||||
this.attachmentsExtractorMode = AttachmentsExtractorMode.valueOf(attachmentsExtractorMode);
|
||||
}
|
||||
|
||||
public void setMimetypeService(MimetypeService mimetypeService)
|
||||
{
|
||||
this.mimetypeService = mimetypeService;
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
attachmentsFolderRef = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<NodeRef>()
|
||||
{
|
||||
public NodeRef doWork() throws Exception
|
||||
{
|
||||
NodeRef attFolderRef = attachmentsFolder.getOrCreateFolderPath(serviceRegistry.getNamespaceService(), nodeService, serviceRegistry.getSearchService(), fileFolderService);
|
||||
serviceRegistry.getPermissionService().setPermission(attFolderRef , PermissionService.ALL_AUTHORITIES, PermissionService.FULL_CONTROL, true);
|
||||
return attFolderRef;
|
||||
RetryingTransactionHelper helper = serviceRegistry.getTransactionService().getRetryingTransactionHelper();
|
||||
helper.setForceWritable(true);
|
||||
RetryingTransactionCallback<NodeRef> getDescriptorCallback = new RetryingTransactionCallback<NodeRef>()
|
||||
{
|
||||
public NodeRef execute()
|
||||
{
|
||||
NodeRef attFolderRef = attachmentsFolder.getOrCreateFolderPath(serviceRegistry.getNamespaceService(), nodeService, serviceRegistry.getSearchService(), fileFolderService);
|
||||
if (attachmentsExtractorMode!=null && attachmentsExtractorMode==AttachmentsExtractorMode.COMMON)
|
||||
{
|
||||
serviceRegistry.getPermissionService().setPermission(attFolderRef , PermissionService.ALL_AUTHORITIES, PermissionService.FULL_CONTROL, true);
|
||||
}
|
||||
return attFolderRef;
|
||||
}
|
||||
};
|
||||
return helper.doInTransaction(getDescriptorCallback, false, false);
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
@@ -123,6 +147,8 @@ public class AttachmentsExtractor
|
||||
public void extractAttachments(NodeRef messageRef, MimeMessage originalMessage) throws IOException, MessagingException
|
||||
{
|
||||
NodeRef attachmentsFolderRef = null;
|
||||
String attachmentsFolderName = null;
|
||||
boolean createFolder = false;
|
||||
switch (attachmentsExtractorMode)
|
||||
{
|
||||
case SAME:
|
||||
@@ -133,14 +159,15 @@ public class AttachmentsExtractor
|
||||
break;
|
||||
case SEPARATE:
|
||||
default:
|
||||
NodeRef parentFolder = nodeService.getPrimaryParent(messageRef).getParentRef();
|
||||
String messageName = (String) nodeService.getProperty(messageRef, ContentModel.PROP_NAME);
|
||||
String attachmentsFolderName = messageName + "-attachments";
|
||||
attachmentsFolderRef = fileFolderService.create(parentFolder, attachmentsFolderName, ContentModel.TYPE_FOLDER).getNodeRef();
|
||||
attachmentsFolderName = messageName + "-attachments";
|
||||
createFolder = true;
|
||||
break;
|
||||
}
|
||||
|
||||
nodeService.createAssociation(messageRef, attachmentsFolderRef, ImapModel.ASSOC_IMAP_ATTACHMENTS_FOLDER);
|
||||
if (!createFolder)
|
||||
{
|
||||
nodeService.createAssociation(messageRef, attachmentsFolderRef, ImapModel.ASSOC_IMAP_ATTACHMENTS_FOLDER);
|
||||
}
|
||||
|
||||
Object content = originalMessage.getContent();
|
||||
if (content instanceof Multipart)
|
||||
@@ -152,6 +179,11 @@ public class AttachmentsExtractor
|
||||
Part part = multipart.getBodyPart(i);
|
||||
if ("attachment".equalsIgnoreCase(part.getDisposition()))
|
||||
{
|
||||
if (createFolder)
|
||||
{
|
||||
attachmentsFolderRef = createAttachmentFolder(messageRef, attachmentsFolderName);
|
||||
createFolder = false;
|
||||
}
|
||||
createAttachment(messageRef, attachmentsFolderRef, part);
|
||||
}
|
||||
}
|
||||
@@ -159,6 +191,24 @@ public class AttachmentsExtractor
|
||||
|
||||
}
|
||||
|
||||
private NodeRef createAttachmentFolder(NodeRef messageRef, String attachmentsFolderName)
|
||||
{
|
||||
NodeRef attachmentsFolderRef = null;
|
||||
NodeRef parentFolder = nodeService.getPrimaryParent(messageRef).getParentRef();
|
||||
attachmentsFolderRef = fileFolderService.create(parentFolder, attachmentsFolderName, ContentModel.TYPE_FOLDER).getNodeRef();
|
||||
nodeService.createAssociation(messageRef, attachmentsFolderRef, ImapModel.ASSOC_IMAP_ATTACHMENTS_FOLDER);
|
||||
return attachmentsFolderRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an attachment given a mime part
|
||||
*
|
||||
* @param messageFile the file containing the message
|
||||
* @param destinationFolder where to put the attachment
|
||||
* @param part the mime part
|
||||
* @throws MessagingException
|
||||
* @throws IOException
|
||||
*/
|
||||
private void createAttachment(NodeRef messageFile, NodeRef attachmentsFolderRef, Part part) throws MessagingException, IOException
|
||||
{
|
||||
String fileName = part.getFileName();
|
||||
@@ -179,42 +229,79 @@ public class AttachmentsExtractor
|
||||
}
|
||||
|
||||
ContentType contentType = new ContentType(part.getContentType());
|
||||
NodeRef attachmentFile = fileFolderService.searchSimple(attachmentsFolderRef, fileName);
|
||||
// The one possible behaviour
|
||||
/*
|
||||
if (result.size() > 0)
|
||||
|
||||
if (contentType.getBaseType().equalsIgnoreCase("application/ms-tnef"))
|
||||
{
|
||||
for (FileInfo fi : result)
|
||||
// The content is TNEF
|
||||
HMEFMessage hmef = new HMEFMessage(part.getInputStream());
|
||||
|
||||
// hmef.getBody();
|
||||
List<org.apache.poi.hmef.Attachment> attachments = hmef.getAttachments();
|
||||
for (org.apache.poi.hmef.Attachment attachment : attachments)
|
||||
{
|
||||
fileFolderService.delete(fi.getNodeRef());
|
||||
String subName = attachment.getLongFilename();
|
||||
|
||||
NodeRef attachmentNode = fileFolderService.searchSimple(attachmentsFolderRef, subName);
|
||||
if (attachmentNode == null)
|
||||
{
|
||||
/*
|
||||
* If the node with the given name does not already exist Create the content node to contain the attachment
|
||||
*/
|
||||
FileInfo createdFile = fileFolderService.create(attachmentsFolderRef, subName, ContentModel.TYPE_CONTENT);
|
||||
|
||||
attachmentNode = createdFile.getNodeRef();
|
||||
|
||||
serviceRegistry.getNodeService().createAssociation(messageFile, attachmentNode, ImapModel.ASSOC_IMAP_ATTACHMENT);
|
||||
|
||||
byte[] bytes = attachment.getContents();
|
||||
ContentWriter writer = fileFolderService.getWriter(attachmentNode);
|
||||
|
||||
// TODO ENCODING - attachment.getAttribute(TNEFProperty.);
|
||||
String extension = attachment.getExtension();
|
||||
String mimetype = mimetypeService.getMimetype(extension);
|
||||
if (mimetype != null)
|
||||
{
|
||||
writer.setMimetype(mimetype);
|
||||
}
|
||||
|
||||
OutputStream os = writer.getContentOutputStream();
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
|
||||
FileCopyUtils.copy(is, os);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
// And another one behaviour which will overwrite the content of the existing file. It is performance preferable.
|
||||
if (attachmentFile == null)
|
||||
{
|
||||
FileInfo createdFile = fileFolderService.create(attachmentsFolderRef, fileName, ContentModel.TYPE_CONTENT);
|
||||
nodeService.createAssociation(messageFile, createdFile.getNodeRef(), ImapModel.ASSOC_IMAP_ATTACHMENT);
|
||||
attachmentFile = createdFile.getNodeRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
else
|
||||
{
|
||||
// not TNEF
|
||||
NodeRef attachmentFile = fileFolderService.searchSimple(attachmentsFolderRef, fileName);
|
||||
// The one possible behaviour
|
||||
/*
|
||||
* if (result.size() > 0) { for (FileInfo fi : result) { fileFolderService.delete(fi.getNodeRef()); } }
|
||||
*/
|
||||
// And another one behaviour which will overwrite the content of the existing file. It is performance preferable.
|
||||
if (attachmentFile == null)
|
||||
{
|
||||
FileInfo createdFile = fileFolderService.create(attachmentsFolderRef, fileName, ContentModel.TYPE_CONTENT);
|
||||
nodeService.createAssociation(messageFile, createdFile.getNodeRef(), ImapModel.ASSOC_IMAP_ATTACHMENT);
|
||||
attachmentFile = createdFile.getNodeRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
String newFileName = imapService.generateUniqueFilename(attachmentsFolderRef, fileName);
|
||||
|
||||
String newFileName = imapService.generateUniqueFilename(attachmentsFolderRef, fileName);
|
||||
|
||||
FileInfo createdFile = fileFolderService.create(attachmentsFolderRef, newFileName, ContentModel.TYPE_CONTENT);
|
||||
nodeService.createAssociation(messageFile, createdFile.getNodeRef(), ImapModel.ASSOC_IMAP_ATTACHMENT);
|
||||
attachmentFile = createdFile.getNodeRef();
|
||||
FileInfo createdFile = fileFolderService.create(attachmentsFolderRef, newFileName, ContentModel.TYPE_CONTENT);
|
||||
nodeService.createAssociation(messageFile, createdFile.getNodeRef(), ImapModel.ASSOC_IMAP_ATTACHMENT);
|
||||
attachmentFile = createdFile.getNodeRef();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
nodeService.setProperty(attachmentFile, ContentModel.PROP_DESCRIPTION, nodeService.getProperty(messageFile, ContentModel.PROP_NAME));
|
||||
|
||||
ContentWriter writer = fileFolderService.getWriter(attachmentFile);
|
||||
writer.setMimetype(contentType.getBaseType());
|
||||
OutputStream os = writer.getContentOutputStream();
|
||||
FileCopyUtils.copy(part.getInputStream(), os);
|
||||
}
|
||||
nodeService.setProperty(attachmentFile, ContentModel.PROP_DESCRIPTION, nodeService.getProperty(messageFile, ContentModel.PROP_NAME));
|
||||
|
||||
ContentWriter writer = fileFolderService.getWriter(attachmentFile);
|
||||
writer.setMimetype(contentType.getBaseType());
|
||||
OutputStream os = writer.getContentOutputStream();
|
||||
FileCopyUtils.copy(part.getInputStream(), os);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,764 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.imap;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.Folder;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Store;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.mail.internet.MimeMultipart;
|
||||
import javax.mail.internet.MimeUtility;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ImapModel;
|
||||
import org.alfresco.repo.importer.ACPImportPackageHandler;
|
||||
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
|
||||
import org.alfresco.repo.node.integrity.IntegrityChecker;
|
||||
import org.alfresco.repo.search.QueryParameterDefImpl;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileFolderUtil;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.QueryParameterDefinition;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.cmr.view.ImporterService;
|
||||
import org.alfresco.service.cmr.view.Location;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
import org.alfresco.util.config.RepositoryFolderConfigBean;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
|
||||
import com.sun.mail.iap.ProtocolException;
|
||||
import com.sun.mail.iap.Response;
|
||||
import com.sun.mail.imap.IMAPFolder;
|
||||
import com.sun.mail.imap.protocol.BODY;
|
||||
import com.sun.mail.imap.protocol.FetchResponse;
|
||||
import com.sun.mail.imap.protocol.IMAPProtocol;
|
||||
import com.sun.mail.imap.protocol.IMAPResponse;
|
||||
import com.sun.mail.imap.protocol.RFC822DATA;
|
||||
import com.sun.mail.imap.protocol.UID;
|
||||
import com.sun.mail.util.ASCIIUtility;
|
||||
|
||||
public class ImapMessageTest extends TestCase
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(ImapMessageTest.class);
|
||||
|
||||
// IMAP client settings
|
||||
private static final String PROTOCOL = "imap";
|
||||
private static final String HOST = "localhost";
|
||||
private static final int PORT = 7143;
|
||||
|
||||
private static final String ADMIN_USER_NAME = "admin";
|
||||
private static final String ADMIN_USER_PASSWORD = "admin";
|
||||
private static final String IMAP_FOLDER_NAME = "test";
|
||||
|
||||
private Session session = null;
|
||||
private Store store = null;
|
||||
private IMAPFolder folder = null;
|
||||
|
||||
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||
private ServiceRegistry serviceRegistry;
|
||||
private TransactionService transactionService;
|
||||
private NodeService nodeService;
|
||||
private ImporterService importerService;
|
||||
private PersonService personService;
|
||||
private SearchService searchService;
|
||||
private NamespaceService namespaceService;
|
||||
private FileFolderService fileFolderService;
|
||||
private MutableAuthenticationService authenticationService;
|
||||
private AlfrescoImapServer imapServer;
|
||||
|
||||
String anotherUserName;
|
||||
private NodeRef testImapFolderNodeRef;
|
||||
private NodeRef storeRootNodeRef;
|
||||
private final String storePath = "workspace://SpacesStore";
|
||||
private final String companyHomePathInStore = "/app:company_home";
|
||||
|
||||
private static final String TEST_FOLDER = "Alfresco IMAP/" + IMAP_FOLDER_NAME + "/___-___folder_a/" + "___-___folder_a_a";
|
||||
private static final String TEST_FILE = "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME + "/" + NamespaceService.CONTENT_MODEL_PREFIX
|
||||
+ ":___-___folder_a/" + NamespaceService.CONTENT_MODEL_PREFIX + ":___-___folder_a_a/" + NamespaceService.CONTENT_MODEL_PREFIX + ":___-___file_a_a";
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
logger.debug("In SetUp");
|
||||
serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
|
||||
transactionService = serviceRegistry.getTransactionService();
|
||||
nodeService = serviceRegistry.getNodeService();
|
||||
importerService = serviceRegistry.getImporterService();
|
||||
personService = serviceRegistry.getPersonService();
|
||||
authenticationService = serviceRegistry.getAuthenticationService();
|
||||
searchService = serviceRegistry.getSearchService();
|
||||
namespaceService = serviceRegistry.getNamespaceService();
|
||||
fileFolderService = serviceRegistry.getFileFolderService();
|
||||
|
||||
|
||||
// start the transaction
|
||||
UserTransaction txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
authenticationService.authenticate(ADMIN_USER_NAME, ADMIN_USER_PASSWORD.toCharArray());
|
||||
|
||||
// downgrade integrity
|
||||
IntegrityChecker.setWarnInTransaction();
|
||||
|
||||
anotherUserName = "user" + System.currentTimeMillis();
|
||||
|
||||
PropertyMap testUser = new PropertyMap();
|
||||
testUser.put(ContentModel.PROP_USERNAME, anotherUserName);
|
||||
testUser.put(ContentModel.PROP_FIRSTNAME, anotherUserName);
|
||||
testUser.put(ContentModel.PROP_LASTNAME, anotherUserName);
|
||||
testUser.put(ContentModel.PROP_EMAIL, anotherUserName + "@alfresco.com");
|
||||
testUser.put(ContentModel.PROP_JOBTITLE, "jobTitle");
|
||||
|
||||
personService.createPerson(testUser);
|
||||
|
||||
// create the ACEGI Authentication instance for the new user
|
||||
authenticationService.createAuthentication(anotherUserName, anotherUserName.toCharArray());
|
||||
|
||||
StoreRef storeRef = new StoreRef(storePath);
|
||||
storeRootNodeRef = nodeService.getRootNode(storeRef);
|
||||
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
|
||||
NodeRef companyHomeNodeRef = nodeRefs.get(0);
|
||||
|
||||
nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME, null,
|
||||
namespaceService, false);
|
||||
if (nodeRefs != null && nodeRefs.size() > 0)
|
||||
{
|
||||
fileFolderService.delete(nodeRefs.get(0));
|
||||
}
|
||||
|
||||
ChildApplicationContextFactory imap = (ChildApplicationContextFactory) ctx.getBean("imap");
|
||||
ApplicationContext imapCtx = imap.getApplicationContext();
|
||||
ImapServiceImpl imapServiceImpl = (ImapServiceImpl) imapCtx.getBean("imapService");
|
||||
imapServer = (AlfrescoImapServer) imapCtx.getBean("imapServer");
|
||||
|
||||
if(!imapServer.isImapServerEnabled())
|
||||
{
|
||||
imapServer.setImapServerEnabled(true);
|
||||
imapServer.setHost(HOST);
|
||||
imapServer.setPort(PORT);
|
||||
imapServer.startup();
|
||||
}
|
||||
|
||||
// Creating IMAP test folder for IMAP root
|
||||
LinkedList<String> folders = new LinkedList<String>();
|
||||
folders.add(IMAP_FOLDER_NAME);
|
||||
FileFolderUtil.makeFolders(fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER);
|
||||
|
||||
// Setting IMAP root
|
||||
RepositoryFolderConfigBean imapHome = new RepositoryFolderConfigBean();
|
||||
imapHome.setStore(storePath);
|
||||
imapHome.setRootPath(companyHomePathInStore);
|
||||
imapHome.setFolderPath(NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME);
|
||||
imapServiceImpl.setImapHome(imapHome);
|
||||
|
||||
|
||||
// Starting IMAP
|
||||
imapServiceImpl.startupInTxn(true);
|
||||
|
||||
nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME, null,
|
||||
namespaceService, false);
|
||||
testImapFolderNodeRef = nodeRefs.get(0);
|
||||
|
||||
/*
|
||||
* Importing test folders: Test folder contains: "___-___folder_a" "___-___folder_a" contains: "___-___folder_a_a", "___-___file_a", "Message_485.eml" (this is IMAP
|
||||
* Message) "___-___folder_a_a" contains: "____-____file_a_a"
|
||||
*/
|
||||
importInternal("imap/imapservice_test_folder_a.acp", testImapFolderNodeRef);
|
||||
|
||||
txn.commit();
|
||||
|
||||
// Init mail client session
|
||||
Properties props = new Properties();
|
||||
props.setProperty("mail.imap.partialfetch", "false");
|
||||
this.session = Session.getDefaultInstance(props, null);
|
||||
|
||||
// Get the store
|
||||
this.store = session.getStore(PROTOCOL);
|
||||
//this.store.connect(HOST, PORT, anotherUserName, anotherUserName);
|
||||
this.store.connect(imapServer.getHost(), imapServer.getPort(), anotherUserName, anotherUserName);
|
||||
|
||||
// Get folder
|
||||
folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
|
||||
folder.open(Folder.READ_ONLY);
|
||||
|
||||
logger.debug("End SetUp");
|
||||
|
||||
}
|
||||
|
||||
private void importInternal(String acpName, NodeRef space) throws IOException
|
||||
{
|
||||
// Importing IMAP test acp
|
||||
ClassPathResource acpResource = new ClassPathResource(acpName);
|
||||
ACPImportPackageHandler acpHandler = new ACPImportPackageHandler(acpResource.getFile(), null);
|
||||
Location importLocation = new Location(space);
|
||||
importerService.importView(acpHandler, importLocation, null, null);
|
||||
}
|
||||
|
||||
public void testMessageModifiedBetweenReads() throws Exception
|
||||
{
|
||||
// Get test message UID
|
||||
final Long uid = getMessageUid(folder, 1);
|
||||
|
||||
// Get unmodified message
|
||||
BODY body = getMessageBody(folder, uid);
|
||||
|
||||
// Parse the multipart MIME message
|
||||
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new BufferedInputStream(body.getByteArrayInputStream()));
|
||||
|
||||
// Reading first part - should be successful
|
||||
MimeMultipart content = (MimeMultipart) message.getContent();
|
||||
assertNotNull(content.getBodyPart(0).getContent());
|
||||
// Reading second part - should be successful
|
||||
assertNotNull(content.getBodyPart(1).getContent());
|
||||
|
||||
// Modify message. The size of letter describing the node may change
|
||||
// These changes should be committed because it should be visible from client
|
||||
NodeRef contentNode = findNode(companyHomePathInStore + TEST_FILE);
|
||||
UserTransaction txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
ContentWriter writer = fileFolderService.getWriter(contentNode);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < 2000; i++)
|
||||
{
|
||||
sb.append("test string");
|
||||
}
|
||||
writer.putContent(sb.toString());
|
||||
txn.commit();
|
||||
|
||||
// Read updated message part
|
||||
BODY bodyNew = getMessageBody(folder, uid);
|
||||
|
||||
// The body should be updated
|
||||
assertFalse(Arrays.equals(bodyNew.data.getBytes(), body.data.getBytes()));
|
||||
|
||||
// Parse the multipart MIME message
|
||||
message = new MimeMessage(Session.getDefaultInstance(new Properties()), new BufferedInputStream(bodyNew.getByteArrayInputStream()));
|
||||
|
||||
// Reading first part - should be successful
|
||||
content = (MimeMultipart) message.getContent();
|
||||
assertNotNull(content.getBodyPart(0).getContent());
|
||||
// Reading second part - should be successful
|
||||
assertNotNull(content.getBodyPart(1).getContent());
|
||||
}
|
||||
|
||||
public void testMessageRenamedBetweenReads() throws Exception
|
||||
{
|
||||
// Get test message UID
|
||||
final Long uid = getMessageUid(folder, 1);
|
||||
// Get Message size
|
||||
final int count = getMessageSize(folder, uid);
|
||||
|
||||
// Get first part
|
||||
BODY body = getMessageBodyPart(folder, uid, 0, count - 100);
|
||||
|
||||
// Rename message. The size of letter describing the node will change
|
||||
// These changes should be committed because it should be visible from client
|
||||
NodeRef contentNode = findNode(companyHomePathInStore + TEST_FILE);
|
||||
UserTransaction txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
fileFolderService.rename(contentNode, "testtesttesttesttesttesttesttesttesttest");
|
||||
txn.commit();
|
||||
|
||||
// Read second message part
|
||||
BODY bodyRest = getMessageBodyPart(folder, uid, count - 100, 100);
|
||||
|
||||
// Creating and parsing message from 2 parts
|
||||
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new SequenceInputStream(new BufferedInputStream(body.getByteArrayInputStream()),
|
||||
new BufferedInputStream(bodyRest.getByteArrayInputStream())));
|
||||
|
||||
// Reading first part - should be successful
|
||||
MimeMultipart content = (MimeMultipart) message.getContent();
|
||||
assertNotNull(content.getBodyPart(0).getContent());
|
||||
|
||||
try
|
||||
{
|
||||
// Reading second part cause error
|
||||
content.getBodyPart(1).getContent();
|
||||
fail("Should raise an IOException");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void dontTestMessageCache() throws Exception
|
||||
{
|
||||
|
||||
// Create messages
|
||||
NodeRef contentNode = findNode(companyHomePathInStore + TEST_FILE);
|
||||
UserTransaction txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
|
||||
// Create messages more than cache capacity
|
||||
for (int i = 0; i < 51; i++)
|
||||
{
|
||||
FileInfo fi = fileFolderService.create(nodeService.getParentAssocs(contentNode).get(0).getParentRef(), "test" + i, ContentModel.TYPE_CONTENT);
|
||||
ContentWriter writer = fileFolderService.getWriter(fi.getNodeRef());
|
||||
writer.putContent("test");
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
|
||||
// Reload folder
|
||||
folder.close(false);
|
||||
folder = (IMAPFolder) store.getFolder(TEST_FOLDER);
|
||||
folder.open(Folder.READ_ONLY);
|
||||
|
||||
// Read all messages
|
||||
for (int i = 1; i < 51; i++)
|
||||
{
|
||||
// Get test message UID
|
||||
final Long uid = getMessageUid(folder, i);
|
||||
// Get Message size
|
||||
final int count = getMessageSize(folder, uid);
|
||||
|
||||
// Get first part
|
||||
BODY body = getMessageBodyPart(folder, uid, 0, count - 100);
|
||||
// Read second message part
|
||||
BODY bodyRest = getMessageBodyPart(folder, uid, count - 100, 100);
|
||||
|
||||
// Creating and parsing message from 2 parts
|
||||
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new SequenceInputStream(new BufferedInputStream(body.getByteArrayInputStream()),
|
||||
new BufferedInputStream(bodyRest.getByteArrayInputStream())));
|
||||
|
||||
// Reading first part - should be successful
|
||||
MimeMultipart content = (MimeMultipart) message.getContent();
|
||||
assertNotNull(content.getBodyPart(0).getContent());
|
||||
assertNotNull(content.getBodyPart(1).getContent());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void testUnmodifiedMessage() throws Exception
|
||||
{
|
||||
// Get test message UID
|
||||
final Long uid = getMessageUid(folder, 1);
|
||||
// Get Message size
|
||||
final int count = getMessageSize(folder, uid);
|
||||
|
||||
// Make multiple message reading
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
// Get random offset
|
||||
int n = (int) ((int) 100 * Math.random());
|
||||
|
||||
// Get first part
|
||||
BODY body = getMessageBodyPart(folder, uid, 0, count - n);
|
||||
// Read second message part
|
||||
BODY bodyRest = getMessageBodyPart(folder, uid, count - n, n);
|
||||
|
||||
// Creating and parsing message from 2 parts
|
||||
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), new SequenceInputStream(new BufferedInputStream(body.getByteArrayInputStream()),
|
||||
new BufferedInputStream(bodyRest.getByteArrayInputStream())));
|
||||
|
||||
MimeMultipart content = (MimeMultipart) message.getContent();
|
||||
// Reading first part - should be successful
|
||||
assertNotNull(content.getBodyPart(0).getContent());
|
||||
// Reading second part - should be successful
|
||||
assertNotNull(content.getBodyPart(1).getContent());
|
||||
}
|
||||
}
|
||||
|
||||
public void testEncodedFromToAddresses() throws Exception
|
||||
{
|
||||
// RFC1342
|
||||
String addressString = "ars.kov@gmail.com";
|
||||
String personalString = "<EFBFBD>?р<>?ений Ковальчук";
|
||||
InternetAddress address = new InternetAddress(addressString, personalString, "UTF-8");
|
||||
|
||||
// Following method returns the address with quoted personal aka <["<22>?р<>?ений Ковальчук"] <ars.kov@gmail.com>>
|
||||
// NOTE! This should be coincided with RFC822MetadataExtracter. Would 'addresses' be quoted or not?
|
||||
// String decodedAddress = address.toUnicodeString();
|
||||
// So, just using decode, for now
|
||||
String decodedAddress = MimeUtility.decodeText(address.toString());
|
||||
|
||||
// InternetAddress.toString(new Address[] {address}) - is used in the RFC822MetadataExtracter
|
||||
// So, compare with that
|
||||
assertFalse("Non ASCII characters in the address should be encoded", decodedAddress.equals(InternetAddress.toString(new Address[] {address})));
|
||||
|
||||
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
|
||||
|
||||
MimeMessageHelper messageHelper = new MimeMessageHelper(message, false, "UTF-8");
|
||||
|
||||
messageHelper.setText("This is a sample message for ALF-5647");
|
||||
messageHelper.setSubject("This is a sample message for ALF-5647");
|
||||
messageHelper.setFrom(address);
|
||||
messageHelper.addTo(address);
|
||||
messageHelper.addCc(address);
|
||||
|
||||
// Creating the message node in the repository
|
||||
String name = AlfrescoImapConst.MESSAGE_PREFIX + GUID.generate();
|
||||
FileInfo messageFile = fileFolderService.create(testImapFolderNodeRef, name, ContentModel.TYPE_CONTENT);
|
||||
// Writing a content.
|
||||
new IncomingImapMessage(messageFile, serviceRegistry, message);
|
||||
|
||||
// Getting the transformed properties from the repository
|
||||
// cm:originator, cm:addressee, cm:addressees, imap:messageFrom, imap:messageTo, imap:messageCc
|
||||
Map<QName, Serializable> properties = nodeService.getProperties(messageFile.getNodeRef());
|
||||
|
||||
String cmOriginator = (String) properties.get(ContentModel.PROP_ORIGINATOR);
|
||||
String cmAddressee = (String) properties.get(ContentModel.PROP_ADDRESSEE);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> cmAddressees = (List<String>) properties.get(ContentModel.PROP_ADDRESSEES);
|
||||
String imapMessageFrom = (String) properties.get(ImapModel.PROP_MESSAGE_FROM);
|
||||
String imapMessageTo = (String) properties.get(ImapModel.PROP_MESSAGE_TO);
|
||||
String imapMessageCc = (String) properties.get(ImapModel.PROP_MESSAGE_CC);
|
||||
|
||||
assertNotNull(cmOriginator);
|
||||
assertEquals(decodedAddress, cmOriginator);
|
||||
assertNotNull(cmAddressee);
|
||||
assertEquals(decodedAddress, cmAddressee);
|
||||
assertNotNull(cmAddressees);
|
||||
assertEquals(1, cmAddressees.size());
|
||||
assertEquals(decodedAddress, cmAddressees.get(0));
|
||||
assertNotNull(imapMessageFrom);
|
||||
assertEquals(decodedAddress, imapMessageFrom);
|
||||
assertNotNull(imapMessageTo);
|
||||
assertEquals(decodedAddress, imapMessageTo);
|
||||
assertNotNull(imapMessageCc);
|
||||
assertEquals(decodedAddress, imapMessageCc);
|
||||
}
|
||||
|
||||
public void testEightBitMessage() throws Exception
|
||||
{
|
||||
|
||||
Store lstore = session.getStore(PROTOCOL);
|
||||
lstore.connect(imapServer.getHost(), imapServer.getPort(), ADMIN_USER_NAME, ADMIN_USER_PASSWORD);
|
||||
|
||||
String folderName = "Alfresco IMAP/" + IMAP_FOLDER_NAME;
|
||||
|
||||
IMAPFolder lfolder = (IMAPFolder) lstore.getFolder(folderName);
|
||||
lfolder.open(Folder.READ_WRITE);
|
||||
|
||||
InputStream messageFileInputStream1 = null;
|
||||
InputStream messageFileInputStream2 = null;
|
||||
try
|
||||
{
|
||||
ClassPathResource fileResource = new ClassPathResource("imap/test-8bit-message.eml");
|
||||
messageFileInputStream1 = new FileInputStream(fileResource.getFile());
|
||||
Message message = new MimeMessage(Session.getDefaultInstance(new Properties()), messageFileInputStream1);
|
||||
String subject = message.getSubject();
|
||||
|
||||
// get original bytes for further comparation
|
||||
messageFileInputStream2 = new FileInputStream(fileResource.getFile());
|
||||
byte[] original = ASCIIUtility.getBytes(messageFileInputStream2);
|
||||
|
||||
Message[] messages = {message};
|
||||
|
||||
lfolder.appendMessages(messages);
|
||||
|
||||
|
||||
|
||||
// The search is not implemented.
|
||||
// SearchTerm term = new HeaderTerm("X-Alfresco-Unique", "test8bit");
|
||||
// messages = folder.search(term);
|
||||
|
||||
// So wee need to get our test message's UID from the repo
|
||||
|
||||
String messageXPath = companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME + "/*[like(@cm:title, $cm:title, true)]";
|
||||
|
||||
QueryParameterDefinition[] params = new QueryParameterDefinition[1];
|
||||
params[0] = new QueryParameterDefImpl(
|
||||
ContentModel.PROP_TITLE,
|
||||
serviceRegistry.getDictionaryService().getDataType(DataTypeDefinition.TEXT),
|
||||
true,
|
||||
subject);
|
||||
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, messageXPath, params, namespaceService, true);
|
||||
|
||||
|
||||
// does the message exist
|
||||
assertEquals(1, nodeRefs.size());
|
||||
|
||||
NodeRef messageNodeRef = nodeRefs.get(0);
|
||||
|
||||
// get message UID
|
||||
Long dbid = (Long) nodeService.getProperty(messageNodeRef, ContentModel.PROP_NODE_DBID);
|
||||
|
||||
// fetch the massage
|
||||
RFC822DATA data = getRFC822Message(lfolder, dbid);
|
||||
|
||||
assertNotNull("Can't fetch a message from the repositiry", data);
|
||||
|
||||
byte[] processed = ASCIIUtility.getBytes(data.getByteArrayInputStream());
|
||||
|
||||
assertTrue("Original message doesn't coincide to the message processed by the repository", Arrays.equals(original, processed));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (messageFileInputStream1 != null) messageFileInputStream1.close();
|
||||
if (messageFileInputStream2 != null) messageFileInputStream2.close();
|
||||
}
|
||||
|
||||
// close connection
|
||||
lfolder.close(true);
|
||||
lstore.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static RFC822DATA getRFC822Message(final IMAPFolder folder, final long uid) throws MessagingException
|
||||
{
|
||||
return (RFC822DATA) folder.doCommand(new IMAPFolder.ProtocolCommand()
|
||||
{
|
||||
public Object doCommand(IMAPProtocol p) throws ProtocolException
|
||||
{
|
||||
Response[] r = p.command("UID FETCH " + uid + " (RFC822)", null);
|
||||
logResponse(r);
|
||||
Response response = r[r.length - 1];
|
||||
if (!response.isOK())
|
||||
{
|
||||
throw new ProtocolException("Unable to retrieve message in RFC822 format");
|
||||
}
|
||||
|
||||
FetchResponse fetchResponse = (FetchResponse) r[0];
|
||||
return fetchResponse.getItem(RFC822DATA.class);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns BODY object containing desired message fragment
|
||||
*
|
||||
* @param folder Folder containing the message
|
||||
* @param uid Message UID
|
||||
* @param from starting byte
|
||||
* @param count bytes to read
|
||||
* @return BODY containing desired message fragment
|
||||
* @throws MessagingException
|
||||
*/
|
||||
private static BODY getMessageBodyPart(IMAPFolder folder, final Long uid, final Integer from, final Integer count) throws MessagingException
|
||||
{
|
||||
return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand()
|
||||
{
|
||||
public Object doCommand(IMAPProtocol p) throws ProtocolException
|
||||
{
|
||||
Response[] r = p.command("UID FETCH " + uid + " (FLAGS BODY.PEEK[]<" + from + "." + count + ">)", null);
|
||||
logResponse(r);
|
||||
Response response = r[r.length - 1];
|
||||
|
||||
// Grab response
|
||||
if (!response.isOK())
|
||||
{
|
||||
throw new ProtocolException("Unable to retrieve message part <" + from + "." + count + ">");
|
||||
}
|
||||
|
||||
FetchResponse fetchResponse = (FetchResponse) r[0];
|
||||
BODY body = (BODY) fetchResponse.getItem(com.sun.mail.imap.protocol.BODY.class);
|
||||
return body;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds node by its path
|
||||
*
|
||||
* @param path
|
||||
* @return NodeRef
|
||||
*/
|
||||
private NodeRef findNode(String path)
|
||||
{
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, path, null, namespaceService, false);
|
||||
return nodeRefs.size() > 0 ? nodeRefs.get(0) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UID of the first message in folder
|
||||
*
|
||||
* @param folder Folder containing the message
|
||||
* @param msn message sequence number
|
||||
* @return UID of the first message
|
||||
* @throws MessagingException
|
||||
*/
|
||||
private static Long getMessageUid(IMAPFolder folder, final int msn) throws MessagingException
|
||||
{
|
||||
return (Long) folder.doCommand(new IMAPFolder.ProtocolCommand()
|
||||
{
|
||||
public Object doCommand(IMAPProtocol p) throws ProtocolException
|
||||
{
|
||||
String command = "FETCH " + msn + " (UID)";
|
||||
Response[] r = p.command(command, null);
|
||||
logResponse(r);
|
||||
Response response = r[r.length - 1];
|
||||
|
||||
// Grab response
|
||||
if (!response.isOK())
|
||||
{
|
||||
throw new ProtocolException("Unable to retrieve message UID");
|
||||
}
|
||||
|
||||
for(int i = 0 ; i < r.length; i++)
|
||||
{
|
||||
if(r[i] instanceof FetchResponse)
|
||||
{
|
||||
FetchResponse fetchResponse = (FetchResponse) r[0];
|
||||
UID uid = (UID) fetchResponse.getItem(UID.class);
|
||||
logger.debug("MSGNO=" + uid.msgno + ", UID="+uid.uid);
|
||||
return uid.uid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uh-oh - this is where we would intermittently fall over with a class cast exception.
|
||||
* The following code probes why we don't have a FetchResponse
|
||||
*/
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("command="+command);
|
||||
sb.append('\n');
|
||||
sb.append("resp length=" + r.length);
|
||||
sb.append('\n');
|
||||
for(int i = 0 ; i < r.length; i++)
|
||||
{
|
||||
logger.error(r[i]);
|
||||
sb.append("class=" + r[i].getClass().getName());
|
||||
IMAPResponse unexpected = (IMAPResponse)r[i];
|
||||
sb.append("key=" + unexpected.getKey());
|
||||
sb.append("number=" + unexpected.getNumber());
|
||||
sb.append("rest=" + unexpected.getRest());
|
||||
|
||||
sb.append("r[" + i + "]=" + r[i] + '\n');
|
||||
}
|
||||
throw new ProtocolException("getMessageUid: "+ sb.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns size of the message
|
||||
*
|
||||
* @param folder Folder containing the message
|
||||
* @param uid Message UID
|
||||
* @return Returns size of the message
|
||||
* @throws MessagingException
|
||||
*/
|
||||
private static Integer getMessageSize(IMAPFolder folder, final Long uid) throws MessagingException
|
||||
{
|
||||
return getMessageBody(folder, uid).data.getCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a full message body
|
||||
*
|
||||
* @param folder Folder containing the message
|
||||
* @param uid Message UID
|
||||
* @return Returns size of the message
|
||||
* @throws MessagingException
|
||||
*/
|
||||
private static BODY getMessageBody(IMAPFolder folder, final Long uid) throws MessagingException
|
||||
{
|
||||
return (BODY) folder.doCommand(new IMAPFolder.ProtocolCommand()
|
||||
{
|
||||
public Object doCommand(IMAPProtocol p) throws ProtocolException
|
||||
{
|
||||
Response[] r = p.command("UID FETCH " + uid + " (FLAGS BODY.PEEK[])", null);
|
||||
logResponse(r);
|
||||
Response response = r[r.length - 1];
|
||||
|
||||
// Grab response
|
||||
if (!response.isOK())
|
||||
{
|
||||
throw new ProtocolException("Unable to retrieve message size");
|
||||
}
|
||||
FetchResponse fetchResponse = (FetchResponse) r[0];
|
||||
BODY body = (BODY) fetchResponse.getItem(BODY.class);
|
||||
return body;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple util for logging response
|
||||
*
|
||||
* @param r response
|
||||
*/
|
||||
private static void logResponse(Response[] r)
|
||||
{
|
||||
for (int i = 0; i < r.length; i++)
|
||||
{
|
||||
logger.debug(r[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception
|
||||
{
|
||||
// Deleting created test environment
|
||||
logger.debug("tearDown ");
|
||||
|
||||
UserTransaction txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + IMAP_FOLDER_NAME, null,
|
||||
namespaceService, false);
|
||||
if (nodeRefs != null && nodeRefs.size() > 0)
|
||||
{
|
||||
fileFolderService.delete(nodeRefs.get(0));
|
||||
}
|
||||
|
||||
authenticationService.deleteAuthentication(anotherUserName);
|
||||
personService.deletePerson(anotherUserName);
|
||||
|
||||
txn.commit();
|
||||
|
||||
// Closing client connection
|
||||
folder.close(false);
|
||||
store.close();
|
||||
logger.debug("tearDown end");
|
||||
}
|
||||
|
||||
}
|
@@ -282,22 +282,6 @@ public interface ImapService
|
||||
*/
|
||||
public boolean isNodeInSitesLibrary(NodeRef nodeRef);
|
||||
|
||||
|
||||
/**
|
||||
* Extract Attachments
|
||||
*
|
||||
* @param parentFolder
|
||||
* @param messageFile the node ref of the message.
|
||||
* @param originalMessage
|
||||
* @throws IOException
|
||||
* @throws MessagingException
|
||||
*/
|
||||
public NodeRef extractAttachments(
|
||||
NodeRef parentFolder,
|
||||
NodeRef messageFile,
|
||||
MimeMessage originalMessage)
|
||||
throws IOException, MessagingException;
|
||||
|
||||
/**
|
||||
* Determines whether the IMAP server is enabled.
|
||||
*
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -20,11 +20,8 @@ package org.alfresco.repo.imap;
|
||||
|
||||
import static org.alfresco.repo.imap.AlfrescoImapConst.DICTIONARY_TEMPLATE_PREFIX;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -44,13 +41,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import javax.mail.Flags;
|
||||
import javax.mail.Flags.Flag;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Multipart;
|
||||
import javax.mail.Part;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.ContentType;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.mail.internet.MimeUtility;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
@@ -88,9 +81,7 @@ import org.alfresco.service.cmr.preference.PreferenceService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
@@ -111,11 +102,9 @@ import org.alfresco.util.PropertyCheck;
|
||||
import org.alfresco.util.config.RepositoryFolderConfigBean;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.poi.hmef.HMEFMessage;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import com.icegreen.greenmail.store.SimpleStoredMessage;
|
||||
|
||||
@@ -144,7 +133,6 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
|
||||
private PermissionService permissionService;
|
||||
private ServiceRegistry serviceRegistry;
|
||||
private BehaviourFilter policyBehaviourFilter;
|
||||
private MimetypeService mimetypeService;
|
||||
private NamespaceService namespaceService;
|
||||
private SearchService searchService;
|
||||
private AttachmentsExtractor attachmentsExtractor;
|
||||
@@ -248,11 +236,6 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public void setMimetypeService(MimetypeService mimetypeService)
|
||||
{
|
||||
this.mimetypeService = mimetypeService;
|
||||
}
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
@@ -378,7 +361,6 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
|
||||
PropertyCheck.mandatory(this, "defaultToAddress", defaultToAddress);
|
||||
PropertyCheck.mandatory(this, "repositoryTemplatePath", repositoryTemplatePath);
|
||||
PropertyCheck.mandatory(this, "policyBehaviourFilter", policyBehaviourFilter);
|
||||
PropertyCheck.mandatory(this, "mimetypeService", mimetypeService);
|
||||
PropertyCheck.mandatory(this, "namespaceService", namespaceService);
|
||||
PropertyCheck.mandatory(this, "searchService", getSearchService());
|
||||
this.folderCache = new MaxSizeMap<Pair<String,String>, FolderStatus>(folderCacheSize, false);
|
||||
@@ -576,53 +558,53 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
|
||||
return new AlfrescoImapFolder(user.getLogin(), this, serviceRegistry);
|
||||
}
|
||||
final NodeRef root;
|
||||
final List<String> pathElements;
|
||||
List<String> pathElements = null;
|
||||
ImapViewMode viewMode = ImapViewMode.ARCHIVE;
|
||||
int index = mailboxName.indexOf(AlfrescoImapConst.HIERARCHY_DELIMITER);
|
||||
int mountPointId = 0;
|
||||
if (index < 0)
|
||||
|
||||
String rootPath = (index > 0) ? (mailboxName.substring(0, index)) : (mailboxName);
|
||||
|
||||
ImapConfigMountPointsBean imapConfigMountPoint = this.imapConfigMountPoints.get(rootPath);
|
||||
if (imapConfigMountPoint != null)
|
||||
{
|
||||
root = getUserImapHomeRef(user.getLogin());
|
||||
pathElements = Collections.singletonList(mailboxName);
|
||||
mountPointId = this.mountPointIds.get(rootPath);
|
||||
root = imapConfigMountPoint.getFolderPath(serviceRegistry.getNamespaceService(), nodeService, searchService, fileFolderService);
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
pathElements = Arrays.asList(mailboxName.substring(index + 1).split(String.valueOf(AlfrescoImapConst.HIERARCHY_DELIMITER)));
|
||||
}
|
||||
|
||||
viewMode = imapConfigMountPoint.getMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
String rootPath = mailboxName.substring(0, index);
|
||||
ImapConfigMountPointsBean imapConfigMountPoint = this.imapConfigMountPoints.get(rootPath);
|
||||
if (imapConfigMountPoint != null)
|
||||
{
|
||||
mountPointId = this.mountPointIds.get(rootPath);
|
||||
root = imapConfigMountPoint.getFolderPath(serviceRegistry.getNamespaceService(), nodeService, searchService, fileFolderService);
|
||||
pathElements = Arrays.asList(mailboxName.substring(index + 1).split(
|
||||
String.valueOf(AlfrescoImapConst.HIERARCHY_DELIMITER)));
|
||||
viewMode = imapConfigMountPoint.getMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
root = getUserImapHomeRef(user.getLogin());
|
||||
pathElements = Arrays.asList(mailboxName.split(String.valueOf(AlfrescoImapConst.HIERARCHY_DELIMITER)));
|
||||
}
|
||||
root = getUserImapHomeRef(user.getLogin());
|
||||
pathElements = Arrays.asList(mailboxName.split(String.valueOf(AlfrescoImapConst.HIERARCHY_DELIMITER)));
|
||||
}
|
||||
|
||||
FileInfo mailFolder;
|
||||
try
|
||||
{
|
||||
mailFolder = fileFolderService.resolveNamePath(root, pathElements, !mayCreate);
|
||||
if (null != pathElements)
|
||||
{
|
||||
mailFolder = fileFolderService.resolveNamePath(root, pathElements, !mayCreate);
|
||||
}
|
||||
else
|
||||
{
|
||||
mailFolder = fileFolderService.getFileInfo(root);
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(ERROR_CANNOT_GET_A_FOLDER, new String[]
|
||||
{
|
||||
mailboxName
|
||||
});
|
||||
throw new AlfrescoRuntimeException(ERROR_CANNOT_GET_A_FOLDER, new String[] { mailboxName });
|
||||
}
|
||||
if (mailFolder == null)
|
||||
{
|
||||
if (!mayCreate)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(ERROR_CANNOT_GET_A_FOLDER, new String[]
|
||||
{
|
||||
mailboxName
|
||||
});
|
||||
throw new AlfrescoRuntimeException(ERROR_CANNOT_GET_A_FOLDER, new String[] { mailboxName });
|
||||
}
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
@@ -637,8 +619,9 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
|
||||
throw new AlfrescoRuntimeException(ERROR_FOLDER_ALREADY_EXISTS);
|
||||
}
|
||||
}
|
||||
return new AlfrescoImapFolder(mailFolder, user.getLogin(), pathElements.get(pathElements.size() - 1), mailboxName, viewMode,
|
||||
this, serviceRegistry, true, isExtractionEnabled(mailFolder.getNodeRef()), mountPointId);
|
||||
String path = (null != pathElements) ? (pathElements.get(pathElements.size() - 1)) : (rootPath);
|
||||
return new AlfrescoImapFolder(mailFolder, user.getLogin(), path, mailboxName, viewMode, this, serviceRegistry, true, isExtractionEnabled(mailFolder.getNodeRef()),
|
||||
mountPointId);
|
||||
}
|
||||
|
||||
public void deleteMailbox(AlfrescoImapUser user, String mailboxName)
|
||||
@@ -1781,6 +1764,14 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
|
||||
setFlag(childNodeRef, Flags.Flag.DELETED, false);
|
||||
setFlag(childNodeRef, Flags.Flag.SEEN, false);
|
||||
}
|
||||
|
||||
NodeRef folderRef = childAssocRef.getParentRef();
|
||||
long newId = (Long) nodeService.getProperty(childNodeRef, ContentModel.PROP_NODE_DBID);
|
||||
if (nodeService.hasAspect(folderRef, ImapModel.ASPECT_IMAP_FOLDER))
|
||||
{
|
||||
// Force generation of a new change token and updating the UIDVALIDITY
|
||||
getUidValidityTransactionListener(folderRef).recordNewUid(newId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@@ -1883,8 +1874,8 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
|
||||
{
|
||||
long modifDate = System.currentTimeMillis();
|
||||
Long oldMax = (Long) nodeService.getProperty(folderNodeRef, ImapModel.PROP_MAXUID);
|
||||
// Only update UIDVALIDITY if a new node has and ID that is smaller than the old maximum (as UIDs are always meant to increase)
|
||||
if (UidValidityTransactionListener.this.forceNewUidValidity || oldMax == null || UidValidityTransactionListener.this.minUid < oldMax)
|
||||
// Only update UIDVALIDITY if a new node has and ID that is smaller or equals the old maximum (as UIDs are always meant to increase)
|
||||
if (UidValidityTransactionListener.this.forceNewUidValidity || oldMax == null || UidValidityTransactionListener.this.minUid <= oldMax)
|
||||
{
|
||||
nodeService.setProperty(folderNodeRef, ImapModel.PROP_UIDVALIDITY, modifDate);
|
||||
if (logger.isDebugEnabled())
|
||||
@@ -1938,174 +1929,6 @@ public class ImapServiceImpl implements ImapService, OnRestoreNodePolicy, OnCrea
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract attachments from a MimeMessage
|
||||
*
|
||||
* Puts the attachments into a subfolder below the parent folder.
|
||||
*
|
||||
* @return the node ref of the folder containing the attachments or null if there are no
|
||||
* attachments.
|
||||
*/
|
||||
public NodeRef extractAttachments(
|
||||
NodeRef parentFolder,
|
||||
NodeRef messageFile,
|
||||
MimeMessage originalMessage)
|
||||
throws IOException, MessagingException
|
||||
{
|
||||
|
||||
String messageName = (String)nodeService.getProperty(messageFile, ContentModel.PROP_NAME);
|
||||
String attachmentsFolderName = messageName + "-attachments";
|
||||
FileInfo attachmentsFolderFileInfo = null;
|
||||
Object content = originalMessage.getContent();
|
||||
if (content instanceof Multipart)
|
||||
{
|
||||
Multipart multipart = (Multipart) content;
|
||||
|
||||
for (int i = 0, n = multipart.getCount(); i < n; i++)
|
||||
{
|
||||
Part part = multipart.getBodyPart(i);
|
||||
|
||||
if ("attachment".equalsIgnoreCase(part.getDisposition()))
|
||||
{
|
||||
if (attachmentsFolderFileInfo == null)
|
||||
{
|
||||
attachmentsFolderFileInfo = fileFolderService.create(
|
||||
parentFolder,
|
||||
attachmentsFolderName,
|
||||
ContentModel.TYPE_FOLDER);
|
||||
nodeService.createAssociation(
|
||||
messageFile,
|
||||
attachmentsFolderFileInfo.getNodeRef(),
|
||||
ImapModel.ASSOC_IMAP_ATTACHMENTS_FOLDER);
|
||||
}
|
||||
createAttachment(messageFile, attachmentsFolderFileInfo.getNodeRef(), part);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(attachmentsFolderFileInfo != null)
|
||||
{
|
||||
return attachmentsFolderFileInfo.getNodeRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an attachment given a mime part
|
||||
*
|
||||
* @param messageFile the file containing the message
|
||||
* @param destinationFolder where to put the attachment
|
||||
* @param part the mime part
|
||||
*
|
||||
* @throws MessagingException
|
||||
* @throws IOException
|
||||
*/
|
||||
private void createAttachment(NodeRef messageFile, NodeRef destinationFolder, Part part) throws MessagingException, IOException
|
||||
{
|
||||
String fileName = part.getFileName();
|
||||
try
|
||||
{
|
||||
fileName = MimeUtility.decodeText(fileName);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn("Cannot decode file name '" + fileName + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
ContentType contentType = new ContentType(part.getContentType());
|
||||
|
||||
if(contentType.getBaseType().equalsIgnoreCase("application/ms-tnef"))
|
||||
{
|
||||
// The content is TNEF
|
||||
HMEFMessage hmef = new HMEFMessage(part.getInputStream());
|
||||
|
||||
//hmef.getBody();
|
||||
List<org.apache.poi.hmef.Attachment> attachments = hmef.getAttachments();
|
||||
for(org.apache.poi.hmef.Attachment attachment : attachments)
|
||||
{
|
||||
String subName = attachment.getLongFilename();
|
||||
|
||||
NodeRef attachmentNode = fileFolderService.searchSimple(destinationFolder, subName);
|
||||
if (attachmentNode == null)
|
||||
{
|
||||
/*
|
||||
* If the node with the given name does not already exist
|
||||
* Create the content node to contain the attachment
|
||||
*/
|
||||
FileInfo createdFile = fileFolderService.create(
|
||||
destinationFolder,
|
||||
subName,
|
||||
ContentModel.TYPE_CONTENT);
|
||||
|
||||
attachmentNode = createdFile.getNodeRef();
|
||||
|
||||
serviceRegistry.getNodeService().createAssociation(
|
||||
messageFile,
|
||||
attachmentNode,
|
||||
ImapModel.ASSOC_IMAP_ATTACHMENT);
|
||||
|
||||
|
||||
byte[] bytes = attachment.getContents();
|
||||
ContentWriter writer = fileFolderService.getWriter(attachmentNode);
|
||||
|
||||
//TODO ENCODING - attachment.getAttribute(TNEFProperty.);
|
||||
String extension = attachment.getExtension();
|
||||
String mimetype = mimetypeService.getMimetype(extension);
|
||||
if(mimetype != null)
|
||||
{
|
||||
writer.setMimetype(mimetype);
|
||||
}
|
||||
|
||||
OutputStream os = writer.getContentOutputStream();
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
|
||||
FileCopyUtils.copy(is, os);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not TNEF
|
||||
NodeRef attachmentNode = fileFolderService.searchSimple(destinationFolder, fileName);
|
||||
if (attachmentNode == null)
|
||||
{
|
||||
/*
|
||||
* If the node with the given name does not already exist
|
||||
* Create the content node to contain the attachment
|
||||
*/
|
||||
FileInfo createdFile = fileFolderService.create(
|
||||
destinationFolder,
|
||||
fileName,
|
||||
ContentModel.TYPE_CONTENT);
|
||||
|
||||
attachmentNode = createdFile.getNodeRef();
|
||||
|
||||
serviceRegistry.getNodeService().createAssociation(
|
||||
messageFile,
|
||||
attachmentNode,
|
||||
ImapModel.ASSOC_IMAP_ATTACHMENT);
|
||||
|
||||
|
||||
// the part is a normal IMAP attachment
|
||||
ContentWriter writer = fileFolderService.getWriter(attachmentNode);
|
||||
writer.setMimetype(contentType.getBaseType());
|
||||
|
||||
String charset = contentType.getParameter("charset");
|
||||
if(charset != null)
|
||||
{
|
||||
writer.setEncoding(charset);
|
||||
}
|
||||
|
||||
OutputStream os = writer.getContentOutputStream();
|
||||
FileCopyUtils.copy(part.getInputStream(), os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setNamespaceService(NamespaceService namespaceService)
|
||||
{
|
||||
this.namespaceService = namespaceService;
|
||||
|
@@ -1,225 +0,0 @@
|
||||
package org.alfresco.repo.imap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileFolderUtil;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.alfresco.util.config.RepositoryFolderConfigBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import com.icegreen.greenmail.store.SimpleStoredMessage;
|
||||
|
||||
/**
|
||||
* Unit test for cache implementation in the ImapServiceImpl. Based on ImapServiceImplTest, but
|
||||
* we need this separate test because we need to get transactions to commit to trigger behaviours in ImapServiceImpl.
|
||||
*
|
||||
* @author ArsenyKo
|
||||
*/
|
||||
public class ImapServiceImplCacheTest extends TestCase
|
||||
{
|
||||
private static final String USER_NAME = "admin";
|
||||
private static final String USER_PASSWORD = "admin";
|
||||
|
||||
private static final String TEST_IMAP_FOLDER_NAME = "aaa";
|
||||
|
||||
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||
private NodeService nodeService;
|
||||
private MutableAuthenticationService authenticationService;
|
||||
private SearchService searchService;
|
||||
private NamespaceService namespaceService;
|
||||
private FileFolderService fileFolderService;
|
||||
private ContentService contentService;
|
||||
private FileInfo oldFile;
|
||||
|
||||
private ImapService imapService;
|
||||
|
||||
private NodeRef testImapFolderNodeRef;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
|
||||
nodeService = serviceRegistry.getNodeService();
|
||||
authenticationService = serviceRegistry.getAuthenticationService();
|
||||
imapService = serviceRegistry.getImapService();
|
||||
searchService = serviceRegistry.getSearchService();
|
||||
namespaceService = serviceRegistry.getNamespaceService();
|
||||
fileFolderService = serviceRegistry.getFileFolderService();
|
||||
contentService = serviceRegistry.getContentService();
|
||||
|
||||
authenticationService.authenticate(USER_NAME, USER_PASSWORD.toCharArray());
|
||||
|
||||
String storePath = "workspace://SpacesStore";
|
||||
String companyHomePathInStore = "/app:company_home";
|
||||
|
||||
StoreRef storeRef = new StoreRef(storePath);
|
||||
|
||||
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
|
||||
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
|
||||
NodeRef companyHomeNodeRef = nodeRefs.get(0);
|
||||
|
||||
ChildApplicationContextFactory imap = (ChildApplicationContextFactory) ctx.getBean("imap");
|
||||
ApplicationContext imapCtx = imap.getApplicationContext();
|
||||
final ImapServiceImpl imapServiceImpl = (ImapServiceImpl)imapCtx.getBean("imapService");
|
||||
|
||||
// Creating IMAP test folder for IMAP root
|
||||
LinkedList<String> folders = new LinkedList<String>();
|
||||
folders.add(TEST_IMAP_FOLDER_NAME);
|
||||
FileInfo folder = FileFolderUtil.makeFolders(fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER);
|
||||
oldFile = fileFolderService.create(folder.getNodeRef(), "oldFile", ContentModel.TYPE_CONTENT);
|
||||
|
||||
// Setting IMAP root
|
||||
RepositoryFolderConfigBean imapHome = new RepositoryFolderConfigBean();
|
||||
imapHome.setStore(storePath);
|
||||
imapHome.setRootPath(companyHomePathInStore);
|
||||
imapHome.setFolderPath(NamespaceService.CONTENT_MODEL_PREFIX + ":" + TEST_IMAP_FOLDER_NAME);
|
||||
imapServiceImpl.setImapHome(imapHome);
|
||||
|
||||
// Starting IMAP
|
||||
imapServiceImpl.startupInTxn(true);
|
||||
|
||||
nodeRefs = searchService.selectNodes(storeRootNodeRef,
|
||||
companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + TEST_IMAP_FOLDER_NAME,
|
||||
null,
|
||||
namespaceService,
|
||||
false);
|
||||
testImapFolderNodeRef = nodeRefs.get(0);
|
||||
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception
|
||||
{
|
||||
fileFolderService.delete(testImapFolderNodeRef);
|
||||
}
|
||||
|
||||
|
||||
public void testRepoBehaviourWithFoldersCache() throws Exception
|
||||
{
|
||||
AlfrescoImapUser localUser = new AlfrescoImapUser(USER_NAME + "@alfresco.com", USER_NAME, USER_PASSWORD);
|
||||
String folderName = "ALF9361";
|
||||
String mailbox = "Alfresco IMAP" + AlfrescoImapConst.HIERARCHY_DELIMITER +
|
||||
TEST_IMAP_FOLDER_NAME + AlfrescoImapConst.HIERARCHY_DELIMITER +
|
||||
folderName;
|
||||
int contentItemsCount = 3;
|
||||
// Create a tree like ALF9361/ALF9361_0/sub_0
|
||||
// Mailbox path with default mount point should be like 'Alfresco IMAP/aaa/ALF9361/ALF9361_0/sub_0
|
||||
FileInfo localRootFolder = fileFolderService.create(testImapFolderNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
||||
List<FileInfo> subFolders = new ArrayList<FileInfo>(10);
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
String childMailbox = folderName + "_" + i;
|
||||
FileInfo subFolder = fileFolderService.create(localRootFolder.getNodeRef(), childMailbox, ContentModel.TYPE_FOLDER);
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
String subChildMailbox = "sub_" + j;
|
||||
fileFolderService.create(subFolder.getNodeRef(), subChildMailbox, ContentModel.TYPE_FOLDER);
|
||||
}
|
||||
subFolders.add(subFolder);
|
||||
}
|
||||
// Create content within 'Alfresco IMAP/aaa/ALF9361'
|
||||
createTestContent(localRootFolder, contentItemsCount);
|
||||
// Load the cache
|
||||
imapService.listMailboxes(localUser, "*", false);
|
||||
imapService.listMailboxes(localUser, "*", true);
|
||||
// Get the folder to examine
|
||||
AlfrescoImapFolder folder = imapService.getOrCreateMailbox(localUser, mailbox, true, false);
|
||||
// Check the folder exist via IMAP
|
||||
assertNotNull("Folder wasn't successfully gotten from IMAP", folder);
|
||||
assertEquals(contentItemsCount, folder.getMessageCount());
|
||||
// Check UIDVALIDITY
|
||||
long uidValidityBefore = folder.getUidValidity();
|
||||
// Move in an old file with a smaller UID
|
||||
fileFolderService.move(oldFile.getNodeRef(), folder.getFolderInfo().getNodeRef(), folder.getName());
|
||||
// Get the folder once more and check it was changed since an old child was moved in
|
||||
folder = imapService.getOrCreateMailbox(localUser, mailbox, true, false);
|
||||
// Content count should be increased
|
||||
assertEquals(++contentItemsCount, folder.getMessageCount());
|
||||
long uidValidity = folder.getUidValidity();
|
||||
assertTrue("UIDVALIDITY wasn't incremented", (uidValidity - uidValidityBefore) > 0);
|
||||
// Delete first childMailbox 'ALF9361/ALF9361_0'
|
||||
//System.out.println(" --------------------- DELETE FOLDER --------------------");
|
||||
//System.out.println(" Parent " + localRootFolder.getNodeRef());
|
||||
fileFolderService.delete(subFolders.get(0).getNodeRef());
|
||||
uidValidityBefore = uidValidity;
|
||||
// Try to get deleted child
|
||||
try
|
||||
{
|
||||
String subFolderName = mailbox + AlfrescoImapConst.HIERARCHY_DELIMITER + folderName + "_0";
|
||||
folder = imapService.getOrCreateMailbox(localUser, subFolderName, true, false);
|
||||
fail("The folder still in the cache");
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
// Try to get deleted sub child. If the cache wasn't invalidated we will get it
|
||||
// But it should be connected to AlfrescoImapFolder.isStale() method.
|
||||
// ArsenyKo: I think we should avoid repo API invocation like isStale...
|
||||
try
|
||||
{
|
||||
String subSubFolderName = mailbox + AlfrescoImapConst.HIERARCHY_DELIMITER + mailbox + "_0" + AlfrescoImapConst.HIERARCHY_DELIMITER + "sub_0";
|
||||
folder = imapService.getOrCreateMailbox(localUser, subSubFolderName, true, false);
|
||||
fail("The folder still in the cache");
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
// Do manipulations with a content in the folder to check the cache behaviour
|
||||
folder = imapService.getOrCreateMailbox(localUser, mailbox, true, false);
|
||||
SimpleStoredMessage message = folder.getMessages().get(0);
|
||||
AbstractMimeMessage alfrescoMessage = (AbstractMimeMessage) message.getMimeMessage();
|
||||
long uid = message.getUid();
|
||||
//System.out.println(" --------------------- DELETE FILE --------------------");
|
||||
//System.out.println(" Parent " + folder.getFolderInfo().getNodeRef());
|
||||
// Delete a content
|
||||
fileFolderService.delete(alfrescoMessage.getMessageInfo().getNodeRef());
|
||||
// Get a folder once again. We expect that the folder would be retrieved from the repo,
|
||||
// since its' cache should be invalidated
|
||||
folder = imapService.getOrCreateMailbox(localUser, mailbox, true, false);
|
||||
// Additional check whether messages cache is valid. Messages cache should be recreated
|
||||
//with the new inctance of AlfrescoImapMessage
|
||||
assertTrue("Messages cache is stale", contentItemsCount > folder.getMessageCount());
|
||||
long[] uids = folder.getMessageUids();
|
||||
Arrays.sort(uids);
|
||||
assertFalse("Messages msn cache is stale", Arrays.binarySearch(uids, uid) > 0);
|
||||
assertNull("Message is still in the messages cache", folder.getMessage(uid));
|
||||
//System.out.println(" --------------------- THE END --------------------");
|
||||
fileFolderService.delete(localRootFolder.getNodeRef());
|
||||
|
||||
}
|
||||
|
||||
private List<FileInfo> createTestContent(FileInfo parent, int count)
|
||||
{
|
||||
List<FileInfo> result = new ArrayList<FileInfo>(count);
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
FileInfo contentItem = fileFolderService.create(parent.getNodeRef(), "content_" + i, ContentModel.TYPE_CONTENT, ContentModel.ASSOC_CONTAINS);
|
||||
ContentWriter contentWriter = contentService.getWriter(contentItem.getNodeRef(), ContentModel.PROP_CONTENT, false);
|
||||
contentWriter.setEncoding("UTF-8");
|
||||
contentWriter.putContent("TEST" + i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,622 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.imap;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.Flags;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.ImapModel;
|
||||
import org.alfresco.repo.imap.AlfrescoImapConst.ImapViewMode;
|
||||
import org.alfresco.repo.importer.ACPImportPackageHandler;
|
||||
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
|
||||
import org.alfresco.repo.model.filefolder.FileFolderServiceImpl;
|
||||
import org.alfresco.repo.node.integrity.IntegrityChecker;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.cmr.view.ImporterService;
|
||||
import org.alfresco.service.cmr.view.Location;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
import org.alfresco.util.config.RepositoryFolderConfigBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* Unit test for ImapServiceImpl
|
||||
*/
|
||||
public class ImapServiceImplTest extends TestCase
|
||||
{
|
||||
|
||||
private static final String USER_NAME = "admin";
|
||||
private static final String USER_PASSWORD = "admin";
|
||||
|
||||
private static final String TEST_IMAP_FOLDER_NAME = "aaa";
|
||||
|
||||
private static final String MAILBOX_NAME_A = "mailbox_a";
|
||||
private static final String MAILBOX_NAME_B = "mailbox_b";
|
||||
private static final String MAILBOX_PATTERN = "mailbox*";
|
||||
private static final String FOLDER_PATTERN = "___-___folder*";
|
||||
private static final String FILE_PATTERN = "___-___file*";
|
||||
|
||||
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||
private TransactionService transactionService;
|
||||
private NodeService nodeService;
|
||||
private ImporterService importerService;
|
||||
private PersonService personService;
|
||||
private MutableAuthenticationService authenticationService;
|
||||
private PermissionService permissionService;
|
||||
private SearchService searchService;
|
||||
private NamespaceService namespaceService;
|
||||
private FileFolderService fileFolderService;
|
||||
|
||||
private AlfrescoImapUser user;
|
||||
private ImapService imapService;
|
||||
private UserTransaction txn;
|
||||
|
||||
private NodeRef testImapFolderNodeRef;
|
||||
private Flags flags;
|
||||
|
||||
String anotherUserName;
|
||||
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
|
||||
transactionService = serviceRegistry.getTransactionService();
|
||||
nodeService = serviceRegistry.getNodeService();
|
||||
importerService = serviceRegistry.getImporterService();
|
||||
personService = serviceRegistry.getPersonService();
|
||||
authenticationService = serviceRegistry.getAuthenticationService();
|
||||
permissionService = serviceRegistry.getPermissionService();
|
||||
imapService = serviceRegistry.getImapService();
|
||||
searchService = serviceRegistry.getSearchService();
|
||||
namespaceService = serviceRegistry.getNamespaceService();
|
||||
fileFolderService = serviceRegistry.getFileFolderService();
|
||||
|
||||
|
||||
flags = new Flags();
|
||||
flags.add(Flags.Flag.SEEN);
|
||||
flags.add(Flags.Flag.FLAGGED);
|
||||
flags.add(Flags.Flag.ANSWERED);
|
||||
flags.add(Flags.Flag.DELETED);
|
||||
|
||||
// start the transaction
|
||||
txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
authenticationService.authenticate(USER_NAME, USER_PASSWORD.toCharArray());
|
||||
|
||||
// downgrade integrity
|
||||
IntegrityChecker.setWarnInTransaction();
|
||||
|
||||
anotherUserName = "user" + System.currentTimeMillis();
|
||||
|
||||
PropertyMap testUser = new PropertyMap();
|
||||
testUser.put(ContentModel.PROP_USERNAME, anotherUserName);
|
||||
testUser.put(ContentModel.PROP_FIRSTNAME, anotherUserName);
|
||||
testUser.put(ContentModel.PROP_LASTNAME, anotherUserName);
|
||||
testUser.put(ContentModel.PROP_EMAIL, anotherUserName + "@alfresco.com");
|
||||
testUser.put(ContentModel.PROP_JOBTITLE, "jobTitle");
|
||||
|
||||
personService.createPerson(testUser);
|
||||
|
||||
// create the ACEGI Authentication instance for the new user
|
||||
authenticationService.createAuthentication(anotherUserName, anotherUserName.toCharArray());
|
||||
|
||||
user = new AlfrescoImapUser(anotherUserName + "@alfresco.com", anotherUserName, anotherUserName);
|
||||
|
||||
String storePath = "workspace://SpacesStore";
|
||||
String companyHomePathInStore = "/app:company_home";
|
||||
|
||||
StoreRef storeRef = new StoreRef(storePath);
|
||||
|
||||
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
|
||||
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
|
||||
NodeRef companyHomeNodeRef = nodeRefs.get(0);
|
||||
|
||||
|
||||
|
||||
ChildApplicationContextFactory imap = (ChildApplicationContextFactory) ctx.getBean("imap");
|
||||
ApplicationContext imapCtx = imap.getApplicationContext();
|
||||
ImapServiceImpl imapServiceImpl = (ImapServiceImpl)imapCtx.getBean("imapService");
|
||||
|
||||
// Creating IMAP test folder for IMAP root
|
||||
LinkedList<String> folders = new LinkedList<String>();
|
||||
folders.add(TEST_IMAP_FOLDER_NAME);
|
||||
FileFolderServiceImpl.makeFolders(fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER);
|
||||
|
||||
// Setting IMAP root
|
||||
RepositoryFolderConfigBean imapHome = new RepositoryFolderConfigBean();
|
||||
imapHome.setStore(storePath);
|
||||
imapHome.setRootPath(companyHomePathInStore);
|
||||
imapHome.setFolderPath(NamespaceService.CONTENT_MODEL_PREFIX + ":" + TEST_IMAP_FOLDER_NAME);
|
||||
imapServiceImpl.setImapHome(imapHome);
|
||||
|
||||
// Starting IMAP
|
||||
imapServiceImpl.startupInTxn(true);
|
||||
|
||||
nodeRefs = searchService.selectNodes(storeRootNodeRef,
|
||||
companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + TEST_IMAP_FOLDER_NAME,
|
||||
null,
|
||||
namespaceService,
|
||||
false);
|
||||
testImapFolderNodeRef = nodeRefs.get(0);
|
||||
|
||||
|
||||
/*
|
||||
* Importing test folders:
|
||||
*
|
||||
* Test folder contains: "___-___folder_a"
|
||||
*
|
||||
* "___-___folder_a" contains: "___-___folder_a_a",
|
||||
* "___-___file_a",
|
||||
* "Message_485.eml" (this is IMAP Message)
|
||||
*
|
||||
* "___-___folder_a_a" contains: "____-____file_a_a"
|
||||
*
|
||||
*/
|
||||
importInternal("imap/imapservice_test_folder_a.acp", testImapFolderNodeRef);
|
||||
|
||||
reauthenticate(anotherUserName, anotherUserName);
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
txn.rollback();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void importInternal(String acpName, NodeRef space)
|
||||
throws IOException
|
||||
{
|
||||
ClassPathResource acpResource = new ClassPathResource(acpName);
|
||||
ACPImportPackageHandler acpHandler = new ACPImportPackageHandler(acpResource.getFile(), null);
|
||||
Location importLocation = new Location(space);
|
||||
importerService.importView(acpHandler, importLocation, null, null);
|
||||
}
|
||||
|
||||
private boolean checkMailbox(AlfrescoImapUser user, String mailboxName)
|
||||
{
|
||||
try
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, mailboxName, true, false);
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkSubscribedMailbox(AlfrescoImapUser user, String mailboxName)
|
||||
{
|
||||
List<AlfrescoImapFolder> aifs = imapService.listMailboxes(user, mailboxName, true);
|
||||
boolean present = false;
|
||||
for (AlfrescoImapFolder aif : aifs)
|
||||
{
|
||||
if (aif.getName().equals(mailboxName))
|
||||
{
|
||||
present = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return present;
|
||||
}
|
||||
|
||||
private void reauthenticate(String name, String password)
|
||||
{
|
||||
authenticationService.invalidateTicket(authenticationService.getCurrentTicket());
|
||||
authenticationService.clearCurrentSecurityContext();
|
||||
authenticationService.authenticate(name, password.toCharArray());
|
||||
}
|
||||
|
||||
public void testGetFolder() throws Exception
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
|
||||
assertTrue(checkMailbox(user, MAILBOX_NAME_A));
|
||||
}
|
||||
|
||||
public void testListMailbox() throws Exception
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_B, false, true);
|
||||
List<AlfrescoImapFolder> mf = imapService.listMailboxes(user, MAILBOX_PATTERN, false);
|
||||
assertEquals(2, mf.size());
|
||||
|
||||
boolean foundA = false;
|
||||
boolean foundB = false;
|
||||
|
||||
for(AlfrescoImapFolder folder : mf)
|
||||
{
|
||||
if(MAILBOX_NAME_A.equals(folder.getName()))
|
||||
{
|
||||
foundA = true;
|
||||
}
|
||||
if(MAILBOX_NAME_B.equals(folder.getName()))
|
||||
{
|
||||
foundB = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("folder A found", foundA);
|
||||
assertTrue("folder B found", foundB);
|
||||
|
||||
mf = imapService.listMailboxes(user, MAILBOX_PATTERN, false);
|
||||
assertEquals("can't repeat the listing of folders", 2, mf.size());
|
||||
|
||||
mf = imapService.listMailboxes(user, MAILBOX_PATTERN, false);
|
||||
assertEquals("can't repeat the listing of folders", 2, mf.size());
|
||||
|
||||
/**
|
||||
* The new mailboxes should be subscribed?
|
||||
*/
|
||||
List<AlfrescoImapFolder> aif = imapService.listMailboxes(user, MAILBOX_PATTERN, true);
|
||||
assertEquals("not subscribed to two mailboxes", 2, aif.size());
|
||||
|
||||
/**
|
||||
* Unsubscribe to one of the mailboxes.
|
||||
*/
|
||||
imapService.unsubscribe(user, MAILBOX_NAME_B);
|
||||
List<AlfrescoImapFolder> aif2 = imapService.listMailboxes(user, MAILBOX_PATTERN, true);
|
||||
assertEquals("not subscribed to one mailbox", 1, aif2.size());
|
||||
}
|
||||
|
||||
public void testListSubscribedMailbox() throws Exception
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_B, false, true);
|
||||
imapService.subscribe(user, MAILBOX_NAME_A);
|
||||
imapService.subscribe(user, MAILBOX_NAME_B);
|
||||
List<AlfrescoImapFolder> aif = imapService.listMailboxes(user, MAILBOX_PATTERN, true);
|
||||
assertEquals(aif.size(), 2);
|
||||
|
||||
assertTrue("Can't subscribe mailbox A", checkSubscribedMailbox(user, MAILBOX_NAME_A));
|
||||
assertTrue("Can't subscribe mailbox B", checkSubscribedMailbox(user, MAILBOX_NAME_B));
|
||||
}
|
||||
|
||||
public void testCreateMailbox() throws Exception
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
|
||||
assertTrue("Mailbox isn't created", checkMailbox(user, MAILBOX_NAME_A));
|
||||
}
|
||||
|
||||
public void testDuplicateMailboxes() throws Exception
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
|
||||
try
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
|
||||
fail("Duplicate Mailbox was created");
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testRenameMailbox() throws Exception
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
public void testRenameMailboxDuplicate() throws Exception
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_B, false, true);
|
||||
try
|
||||
{
|
||||
imapService.renameMailbox(user, MAILBOX_NAME_A, MAILBOX_NAME_B);
|
||||
fail("Mailbox was renamed to existing one but shouldn't");
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testDeleteMailbox() throws Exception
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_B, false, true);
|
||||
imapService.deleteMailbox(user, MAILBOX_NAME_B);
|
||||
assertFalse("Can't delete mailbox", checkMailbox(user, MAILBOX_NAME_B));
|
||||
}
|
||||
|
||||
// public void testSearchFoldersInArchive() throws Exception
|
||||
// {
|
||||
// List<FileInfo> fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, true, ImapViewMode.ARCHIVE);
|
||||
// assertNotNull("Can't find folders in Archive Mode", fi);
|
||||
// assertEquals("Can't find folders in Archive Mode", fi.size(), 2);
|
||||
//
|
||||
// fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, false, ImapViewMode.ARCHIVE);
|
||||
// assertNotNull("Can't find folders in Archive Mode", fi);
|
||||
// assertEquals("Can't find folders in Archive Mode", fi.size(), 1);
|
||||
// }
|
||||
//
|
||||
// public void testSearchFoldersInVirtual() throws Exception
|
||||
// {
|
||||
// List<FileInfo> fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, true, ImapViewMode.VIRTUAL);
|
||||
// assertNotNull("Can't find folders in Virtual Mode", fi);
|
||||
// assertEquals("Can't find folders in Virtual Mode", fi.size(), 2);
|
||||
//
|
||||
// fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, false, ImapViewMode.VIRTUAL);
|
||||
// assertNotNull("Can't find folders in Virtual Mode", fi);
|
||||
// assertEquals("Can't find folders in Virtual Mode", fi.size(), 1);
|
||||
// }
|
||||
//
|
||||
// public void testSearchFoldersInMixed() throws Exception
|
||||
// {
|
||||
// List<FileInfo> fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, true, ImapViewMode.MIXED);
|
||||
// assertNotNull("Can't find folders in Mixed Mode", fi);
|
||||
// assertEquals("Can't find folders in Mixed Mode", fi.size(), 2);
|
||||
//
|
||||
// fi = imapService.searchFolders(testImapFolderNodeRef, FOLDER_PATTERN, false, ImapViewMode.MIXED);
|
||||
// assertNotNull("Can't find folders in Mixed Mode", fi);
|
||||
// assertEquals("Can't find folders in Mixed Mode", fi.size(), 1);
|
||||
// }
|
||||
|
||||
// public void testSearchFiles() throws Exception
|
||||
// {
|
||||
// List<FileInfo> fi = imapService.searchFiles(testImapFolderNodeRef, FILE_PATTERN, true);
|
||||
// assertNotNull(fi);
|
||||
// assertTrue(fi.size() > 0);
|
||||
// }
|
||||
//
|
||||
// public void testSearchMails() throws Exception
|
||||
// {
|
||||
// List<FileInfo> fi = imapService.searchMails(testImapFolderNodeRef, ImapViewMode.MIXED);
|
||||
// assertNotNull(fi);
|
||||
// assertTrue(fi.size() > 0);
|
||||
// }
|
||||
|
||||
public void testSubscribe() throws Exception
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
|
||||
|
||||
imapService.subscribe(user, MAILBOX_NAME_A);
|
||||
assertTrue("Can't subscribe mailbox", checkSubscribedMailbox(user, MAILBOX_NAME_A));
|
||||
}
|
||||
|
||||
public void testUnsubscribe() throws Exception
|
||||
{
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_NAME_A, false, true);
|
||||
imapService.subscribe(user, MAILBOX_NAME_A);
|
||||
imapService.unsubscribe(user, MAILBOX_NAME_A);
|
||||
// TODO MER 21/05/2010 : line below looks like a bug to me.
|
||||
assertFalse("Can't unsubscribe mailbox", checkSubscribedMailbox(user, MAILBOX_NAME_A));
|
||||
}
|
||||
|
||||
private void setFlags(FileInfo messageFileInfo) throws Exception
|
||||
{
|
||||
imapService.setFlags(messageFileInfo, flags, true);
|
||||
NodeRef messageNodeRef = messageFileInfo.getNodeRef();
|
||||
Map<QName, Serializable> props = nodeService.getProperties(messageNodeRef);
|
||||
|
||||
assertTrue("Can't set SEEN flag", props.containsKey(ImapModel.PROP_FLAG_SEEN));
|
||||
assertTrue("Can't set FLAGGED flag", props.containsKey(ImapModel.PROP_FLAG_FLAGGED));
|
||||
assertTrue("Can't set ANSWERED flag", props.containsKey(ImapModel.PROP_FLAG_ANSWERED));
|
||||
assertTrue("Can't set DELETED flag", props.containsKey(ImapModel.PROP_FLAG_DELETED));
|
||||
}
|
||||
|
||||
public void testSetFlags() throws Exception
|
||||
{
|
||||
NavigableMap<Long, FileInfo> fis = imapService.getFolderStatus(authenticationService.getCurrentUserName(), testImapFolderNodeRef, ImapViewMode.ARCHIVE).search;
|
||||
if (fis != null && fis.size() > 0)
|
||||
{
|
||||
FileInfo messageFileInfo = fis.firstEntry().getValue();
|
||||
try
|
||||
{
|
||||
setFlags(messageFileInfo);
|
||||
fail("Can't set flags");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof AccessDeniedException)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
else
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
reauthenticate(USER_NAME, USER_PASSWORD);
|
||||
|
||||
permissionService.setPermission(testImapFolderNodeRef, anotherUserName, PermissionService.WRITE, true);
|
||||
|
||||
reauthenticate(anotherUserName, anotherUserName);
|
||||
|
||||
setFlags(messageFileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetFlag() throws Exception
|
||||
{
|
||||
NavigableMap<Long, FileInfo> fis = imapService.getFolderStatus(authenticationService.getCurrentUserName(), testImapFolderNodeRef, ImapViewMode.ARCHIVE).search;
|
||||
if (fis != null && fis.size() > 0)
|
||||
{
|
||||
FileInfo messageFileInfo = fis.firstEntry().getValue();
|
||||
|
||||
reauthenticate(USER_NAME, USER_PASSWORD);
|
||||
|
||||
permissionService.setPermission(testImapFolderNodeRef, anotherUserName, PermissionService.WRITE, true);
|
||||
|
||||
reauthenticate(anotherUserName, anotherUserName);
|
||||
|
||||
imapService.setFlag(messageFileInfo, Flags.Flag.RECENT, true);
|
||||
|
||||
Serializable prop = nodeService.getProperty(messageFileInfo.getNodeRef(), ImapModel.PROP_FLAG_RECENT);
|
||||
assertNotNull("Can't set RECENT flag", prop);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetFlags() throws Exception
|
||||
{
|
||||
NavigableMap<Long, FileInfo> fis = imapService.getFolderStatus(authenticationService.getCurrentUserName(), testImapFolderNodeRef, ImapViewMode.ARCHIVE).search;
|
||||
if (fis != null && fis.size() > 0)
|
||||
{
|
||||
FileInfo messageFileInfo = fis.firstEntry().getValue();
|
||||
|
||||
reauthenticate(USER_NAME, USER_PASSWORD);
|
||||
|
||||
permissionService.setPermission(testImapFolderNodeRef, anotherUserName, PermissionService.WRITE, true);
|
||||
|
||||
imapService.setFlags(messageFileInfo, flags, true);
|
||||
|
||||
reauthenticate(anotherUserName, anotherUserName);
|
||||
|
||||
Flags fl = imapService.getFlags(messageFileInfo);
|
||||
assertTrue(fl.contains(flags));
|
||||
}
|
||||
}
|
||||
|
||||
public void testRenameAccentedMailbox() throws Exception
|
||||
{
|
||||
String MAILBOX_ACCENTED_NAME_A = "Hôtel";
|
||||
String MAILBOX_ACCENTED_NAME_B = "HôtelXX";
|
||||
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_ACCENTED_NAME_A, false, true);
|
||||
imapService.deleteMailbox(user, MAILBOX_ACCENTED_NAME_A);
|
||||
|
||||
imapService.getOrCreateMailbox(user, MAILBOX_ACCENTED_NAME_A, false, true);
|
||||
imapService.renameMailbox(user, MAILBOX_ACCENTED_NAME_A, MAILBOX_ACCENTED_NAME_B);
|
||||
assertFalse("Can't rename mailbox", checkMailbox(user, MAILBOX_ACCENTED_NAME_A));
|
||||
assertTrue("Can't rename mailbox", checkMailbox(user, MAILBOX_ACCENTED_NAME_B));
|
||||
imapService.deleteMailbox(user, MAILBOX_ACCENTED_NAME_B);
|
||||
}
|
||||
|
||||
public void testContentRecovery() throws Exception
|
||||
{
|
||||
reauthenticate(USER_NAME, USER_PASSWORD);
|
||||
|
||||
// create content
|
||||
NodeRef nodeRef = nodeService.createNode(testImapFolderNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "content_recover"), ContentModel.TYPE_CONTENT).getChildRef();
|
||||
FileInfo fileInfo = fileFolderService.getFileInfo(nodeRef);
|
||||
|
||||
// Outlook sets flags that indicates that a content was seen and deleted
|
||||
imapService.setFlag(fileInfo, Flags.Flag.DELETED, true);
|
||||
imapService.setFlag(fileInfo, Flags.Flag.SEEN, true);
|
||||
|
||||
// delete a content
|
||||
fileFolderService.delete(nodeRef);
|
||||
|
||||
// get archive node reference
|
||||
String storePath = "archive://SpacesStore";
|
||||
StoreRef storeRef = new StoreRef(storePath);
|
||||
NodeRef archivedNodeRef = new NodeRef(storeRef, nodeRef.getId());
|
||||
|
||||
// restore a node and check flags
|
||||
Boolean value = false;
|
||||
if (nodeService.exists(archivedNodeRef))
|
||||
{
|
||||
NodeRef restoredNode = nodeService.restoreNode(archivedNodeRef, testImapFolderNodeRef, null, null);
|
||||
|
||||
Map<QName, Serializable> props = nodeService.getProperties(restoredNode);
|
||||
|
||||
if (props.containsKey(ImapModel.PROP_FLAG_DELETED) && props.containsKey(ImapModel.PROP_FLAG_SEEN))
|
||||
{
|
||||
value = !(Boolean) props.get(ImapModel.PROP_FLAG_DELETED) && !(Boolean) props.get(ImapModel.PROP_FLAG_SEEN);
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("Can't set DELETED flag to false", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test attachment extraction with a TNEF message
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAttachmentExtraction() throws Exception
|
||||
{
|
||||
AuthenticationUtil.setRunAsUserSystem();
|
||||
/**
|
||||
* Load a TNEF message
|
||||
*/
|
||||
ClassPathResource fileResource = new ClassPathResource("imap/test-tnef-message.eml");
|
||||
assertNotNull("unable to find test resource test-tnef-message.eml", fileResource);
|
||||
InputStream is = new FileInputStream(fileResource.getFile());
|
||||
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), is);
|
||||
|
||||
/**
|
||||
* Create a test node containing the message
|
||||
*/
|
||||
String storePath = "workspace://SpacesStore";
|
||||
String companyHomePathInStore = "/app:company_home";
|
||||
StoreRef storeRef = new StoreRef(storePath);
|
||||
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
|
||||
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
|
||||
NodeRef companyHomeNodeRef = nodeRefs.get(0);
|
||||
|
||||
FileInfo f1 = fileFolderService.create(companyHomeNodeRef, "ImapServiceImplTest", ContentModel.TYPE_FOLDER);
|
||||
FileInfo d2 = fileFolderService.create(f1.getNodeRef(), "ImapServiceImplTest", ContentModel.TYPE_FOLDER);
|
||||
FileInfo f2 = fileFolderService.create(f1.getNodeRef(), "test-tnef-message.eml", ContentModel.TYPE_CONTENT);
|
||||
|
||||
ContentWriter writer = fileFolderService.getWriter(f2.getNodeRef());
|
||||
writer.putContent(new FileInputStream(fileResource.getFile()));
|
||||
|
||||
NodeRef folder = imapService.extractAttachments(f1.getNodeRef(), f2.getNodeRef(), message);
|
||||
assertNotNull(folder);
|
||||
|
||||
List<FileInfo> files = fileFolderService.listFiles(folder);
|
||||
assertTrue("three files not found", files.size() == 3);
|
||||
|
||||
}
|
||||
}
|
@@ -1,249 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.imap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.mail.Flags;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.importer.ACPImportPackageHandler;
|
||||
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
|
||||
import org.alfresco.repo.model.filefolder.FileFolderServiceImpl;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.cmr.view.ImporterService;
|
||||
import org.alfresco.service.cmr.view.Location;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
import org.alfresco.util.config.RepositoryFolderConfigBean;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import com.icegreen.greenmail.store.SimpleStoredMessage;
|
||||
|
||||
public class LoadTester extends TestCase
|
||||
{
|
||||
private Log logger = LogFactory.getLog(LoadTester.class);
|
||||
|
||||
|
||||
private static final ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||
|
||||
private ImapService imapService;
|
||||
private ImporterService importerService;
|
||||
private MutableAuthenticationService authenticationService;
|
||||
|
||||
private AlfrescoImapUser user;
|
||||
// DH: Do not assume the presence of any specific user or password. Create a new user for the test.
|
||||
private static final String USER_NAME = "admin";
|
||||
private static final String USER_PASSWORD = "admin";
|
||||
private static final String TEST_IMAP_ROOT_FOLDER_NAME = "aaa";
|
||||
private static final String TEST_DATA_FOLDER_NAME = "test_data";
|
||||
private static final String TEST_FOLDER_NAME = "test_imap1000";
|
||||
private static final long MESSAGE_QUANTITY = 1000;
|
||||
|
||||
private String anotherUserName;
|
||||
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
|
||||
authenticationService = serviceRegistry.getAuthenticationService();
|
||||
imapService = serviceRegistry.getImapService();
|
||||
importerService = serviceRegistry.getImporterService();
|
||||
NodeService nodeService = serviceRegistry.getNodeService();
|
||||
SearchService searchService = serviceRegistry.getSearchService();
|
||||
NamespaceService namespaceService = serviceRegistry.getNamespaceService();
|
||||
PersonService personService = serviceRegistry.getPersonService();
|
||||
FileFolderService fileFolderService = serviceRegistry.getFileFolderService();
|
||||
TransactionService transactionService = serviceRegistry.getTransactionService();
|
||||
PermissionService permissionService = serviceRegistry.getPermissionService();
|
||||
|
||||
|
||||
// start the transaction
|
||||
UserTransaction txn = transactionService.getUserTransaction();
|
||||
txn.begin();
|
||||
|
||||
authenticationService.authenticate(USER_NAME, USER_PASSWORD.toCharArray());
|
||||
|
||||
anotherUserName = "test_imap_user";
|
||||
|
||||
NodeRef person = personService.getPerson(anotherUserName);
|
||||
|
||||
if (person != null)
|
||||
{
|
||||
personService.deletePerson(anotherUserName);
|
||||
PropertyMap testUser = new PropertyMap();
|
||||
testUser.put(ContentModel.PROP_USERNAME, anotherUserName);
|
||||
testUser.put(ContentModel.PROP_FIRSTNAME, anotherUserName);
|
||||
testUser.put(ContentModel.PROP_LASTNAME, anotherUserName);
|
||||
testUser.put(ContentModel.PROP_EMAIL, anotherUserName + "@alfresco.com");
|
||||
testUser.put(ContentModel.PROP_JOBTITLE, "jobTitle");
|
||||
personService.createPerson(testUser);
|
||||
|
||||
}
|
||||
if (authenticationService.authenticationExists(anotherUserName))
|
||||
{
|
||||
authenticationService.deleteAuthentication(anotherUserName);
|
||||
}
|
||||
authenticationService.createAuthentication(anotherUserName, anotherUserName.toCharArray());
|
||||
|
||||
|
||||
user = new AlfrescoImapUser(anotherUserName + "@alfresco.com", anotherUserName, anotherUserName);
|
||||
|
||||
String storePath = "workspace://SpacesStore";
|
||||
String companyHomePathInStore = "/app:company_home";
|
||||
|
||||
StoreRef storeRef = new StoreRef(storePath);
|
||||
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
|
||||
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
|
||||
NodeRef companyHomeNodeRef = nodeRefs.get(0);
|
||||
|
||||
ChildApplicationContextFactory imap = (ChildApplicationContextFactory) ctx.getBean("imap");
|
||||
ApplicationContext imapCtx = imap.getApplicationContext();
|
||||
ImapServiceImpl imapServiceImpl = (ImapServiceImpl)imapCtx.getBean("imapService");
|
||||
|
||||
|
||||
// Delete test folder
|
||||
nodeRefs = searchService.selectNodes(storeRootNodeRef,
|
||||
companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + TEST_IMAP_ROOT_FOLDER_NAME,
|
||||
null, namespaceService, false);
|
||||
if (nodeRefs.size() == 1)
|
||||
{
|
||||
NodeRef ch = nodeRefs.get(0);
|
||||
nodeService.deleteNode(ch);
|
||||
}
|
||||
|
||||
|
||||
// Creating IMAP test folder for IMAP root
|
||||
LinkedList<String> folders = new LinkedList<String>();
|
||||
folders.add(TEST_IMAP_ROOT_FOLDER_NAME);
|
||||
FileFolderServiceImpl.makeFolders(fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER);
|
||||
|
||||
// Setting IMAP root
|
||||
RepositoryFolderConfigBean imapHome = new RepositoryFolderConfigBean();
|
||||
imapHome.setStore(storePath);
|
||||
imapHome.setRootPath(companyHomePathInStore);
|
||||
imapHome.setFolderPath(TEST_IMAP_ROOT_FOLDER_NAME);
|
||||
imapServiceImpl.setImapHome(imapHome);
|
||||
|
||||
// Starting IMAP
|
||||
imapServiceImpl.startupInTxn(true);
|
||||
|
||||
nodeRefs = searchService.selectNodes(storeRootNodeRef,
|
||||
companyHomePathInStore + "/" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + TEST_IMAP_ROOT_FOLDER_NAME,
|
||||
null,
|
||||
namespaceService,
|
||||
false);
|
||||
|
||||
// Used to create User's folder
|
||||
NodeRef userFolderRef = imapService.getUserImapHomeRef(anotherUserName);
|
||||
permissionService.setPermission(userFolderRef, anotherUserName, PermissionService.ALL_PERMISSIONS, true);
|
||||
|
||||
importTestData("imap/load_test_data.acp", userFolderRef);
|
||||
|
||||
reauthenticate(anotherUserName, anotherUserName);
|
||||
|
||||
AlfrescoImapFolder testDataFolder = imapService.getOrCreateMailbox(user, TEST_DATA_FOLDER_NAME, true, false);
|
||||
|
||||
SimpleStoredMessage m = testDataFolder.getMessages().get(0);
|
||||
m = testDataFolder.getMessage(m.getUid());
|
||||
|
||||
AlfrescoImapFolder folder = imapService.getOrCreateMailbox(user, TEST_FOLDER_NAME, false, true);
|
||||
|
||||
logger.info("Creating folders...");
|
||||
long t = System.currentTimeMillis();
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < MESSAGE_QUANTITY; i++)
|
||||
{
|
||||
System.out.println("i = " + i);
|
||||
folder.appendMessage(m.getMimeMessage(), new Flags(), new Date());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.error(e, e);
|
||||
}
|
||||
|
||||
t = System.currentTimeMillis() - t;
|
||||
logger.info("Create time: " + t + " ms (" + t/1000 + " s (" + t/60000 + " min))");
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
|
||||
private void reauthenticate(String name, String password)
|
||||
{
|
||||
authenticationService.invalidateTicket(authenticationService.getCurrentTicket());
|
||||
authenticationService.clearCurrentSecurityContext();
|
||||
authenticationService.authenticate(name, password.toCharArray());
|
||||
}
|
||||
|
||||
|
||||
public void tearDown() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public void testList()
|
||||
{
|
||||
logger.info("Listing folders...");
|
||||
|
||||
long t = System.currentTimeMillis();
|
||||
List<AlfrescoImapFolder> list = imapService.listMailboxes(user, TEST_FOLDER_NAME + "*", false);
|
||||
t = System.currentTimeMillis() - t;
|
||||
|
||||
logger.info("List time: " + t + " ms (" + t/1000 + " s)");
|
||||
logger.info("List size: " + list.size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void importTestData(String acpName, NodeRef space) throws IOException
|
||||
{
|
||||
ClassPathResource acpResource = new ClassPathResource(acpName);
|
||||
ACPImportPackageHandler acpHandler = new ACPImportPackageHandler(acpResource.getFile(), null);
|
||||
Location importLocation = new Location(space);
|
||||
importerService.importView(acpHandler, importLocation, null, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@@ -1,250 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.imap;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.BodyPart;
|
||||
import javax.mail.Folder;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.NoSuchProviderException;
|
||||
import javax.mail.Part;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Store;
|
||||
import javax.mail.internet.MimeMultipart;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.sun.mail.util.BASE64DecoderStream;
|
||||
|
||||
public class RemoteLoadTester extends TestCase
|
||||
{
|
||||
|
||||
private Log logger = LogFactory.getLog(RemoteLoadTester.class);
|
||||
|
||||
private static final String USER_NAME = "test_imap_user";
|
||||
private static final String USER_PASSWORD = "test_imap_user";
|
||||
private static final String TEST_FOLDER_NAME = "test_imap1000";
|
||||
|
||||
private static final String ADMIN_USER_NAME = "admin";
|
||||
private static String REMOTE_HOST = "127.0.0.1";
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (args.length > 0)
|
||||
REMOTE_HOST = args[0];
|
||||
new RemoteLoadTester().testListSequence();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void testListSequence()
|
||||
{
|
||||
System.out.println(String.format("Connecting to remote server '%s'", REMOTE_HOST));
|
||||
Properties props = System.getProperties();
|
||||
props.setProperty("mail.imap.partialfetch", "false");
|
||||
Session session = Session.getDefaultInstance(props, null);
|
||||
|
||||
Store store = null;
|
||||
long startTime = 0;
|
||||
long endTime = 0;
|
||||
try
|
||||
{
|
||||
store = session.getStore("imap");
|
||||
store.connect(REMOTE_HOST, ADMIN_USER_NAME, ADMIN_USER_NAME);
|
||||
Folder[] folders = null;
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
folders = store.getDefaultFolder().list("");
|
||||
endTime = System.currentTimeMillis();
|
||||
System.out.println(String.format("LIST '', folders.length = %d, execTime = %d sec", folders.length, (endTime - startTime)/1000));
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
folders = store.getDefaultFolder().list("*");
|
||||
endTime = System.currentTimeMillis();
|
||||
System.out.println(String.format("LIST *, folders.length = %d, execTime = %d sec", folders.length, (endTime - startTime)/1000));
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
folders = store.getDefaultFolder().listSubscribed("*");
|
||||
endTime = System.currentTimeMillis();
|
||||
System.out.println(String.format("LSUB *, folders.length = %d, execTime = %d sec", folders.length, (endTime - startTime)/1000));
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
for (Folder folder : folders)
|
||||
{
|
||||
folder.getMessageCount();
|
||||
//Folder f = store.getFolder(folder.getFullName());
|
||||
}
|
||||
endTime = System.currentTimeMillis();
|
||||
System.out.println(String.format("Folders Loop, folders.length = %d, execTime = %d sec", folders.length, (endTime - startTime)/1000));
|
||||
|
||||
}
|
||||
catch (NoSuchProviderException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
store.close();
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testMailbox()
|
||||
{
|
||||
logger.info("Getting folder...");
|
||||
long t = System.currentTimeMillis();
|
||||
|
||||
// Create empty properties
|
||||
Properties props = new Properties();
|
||||
props.setProperty("mail.imap.partialfetch", "false");
|
||||
|
||||
// Get session
|
||||
Session session = Session.getDefaultInstance(props, null);
|
||||
|
||||
Store store = null;
|
||||
Folder folder = null;
|
||||
try
|
||||
{
|
||||
// Get the store
|
||||
store = session.getStore("imap");
|
||||
store.connect(REMOTE_HOST, USER_NAME, USER_PASSWORD);
|
||||
|
||||
// Get folder
|
||||
folder = store.getFolder(TEST_FOLDER_NAME);
|
||||
folder.open(Folder.READ_ONLY);
|
||||
|
||||
// Get directory
|
||||
Message message[] = folder.getMessages();
|
||||
|
||||
for (int i = 0, n = message.length; i < n; i++)
|
||||
{
|
||||
message[i].getAllHeaders();
|
||||
|
||||
Address[] from = message[i].getFrom();
|
||||
System.out.print(i + ": ");
|
||||
if (from != null)
|
||||
{
|
||||
System.out.print(message[i].getFrom()[0] + "\t");
|
||||
}
|
||||
System.out.println(message[i].getSubject());
|
||||
|
||||
Object content = message[i].getContent();
|
||||
if (content instanceof MimeMultipart)
|
||||
{
|
||||
for (int j = 0, m = ((MimeMultipart)content).getCount(); j < m; j++)
|
||||
{
|
||||
BodyPart part = ((MimeMultipart)content).getBodyPart(j);
|
||||
Object partContent = part.getContent();
|
||||
|
||||
if (partContent instanceof String)
|
||||
{
|
||||
String body = (String)partContent;
|
||||
}
|
||||
else if (partContent instanceof FilterInputStream)
|
||||
{
|
||||
FilterInputStream fis = (FilterInputStream)partContent;
|
||||
BufferedInputStream bis = new BufferedInputStream(fis);
|
||||
|
||||
/* while (bis.available() > 0)
|
||||
{
|
||||
bis.read();
|
||||
}*/
|
||||
byte[] bytes = new byte[524288];
|
||||
while (bis.read(bytes) != -1)
|
||||
{
|
||||
}
|
||||
bis.close();
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nn = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
t = System.currentTimeMillis() - t;
|
||||
logger.info("Time: " + t + " ms (" + t/1000 + " s)");
|
||||
logger.info("Length: " + message.length);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.error(e.getMessage(), e);
|
||||
fail(e.getMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Close connection
|
||||
try
|
||||
{
|
||||
if (folder != null)
|
||||
{
|
||||
folder.close(false);
|
||||
}
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
logger.error(e.getMessage(), e);
|
||||
fail(e.getMessage());
|
||||
}
|
||||
try
|
||||
{
|
||||
if (store != null)
|
||||
{
|
||||
store.close();
|
||||
}
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
logger.error(e.getMessage(), e);
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -14,4 +14,6 @@
|
||||
* @since 3.2
|
||||
*
|
||||
*/
|
||||
package org.alfresco.repo.imap;
|
||||
@PackageMarker
|
||||
package org.alfresco.repo.imap;
|
||||
import org.alfresco.util.PackageMarker;
|
||||
|
Reference in New Issue
Block a user