mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	125788 rmunteanu: Merged 5.1.N (5.1.2) to 5.2.N (5.2.1)
      125606 rmunteanu: Merged 5.1.1 (5.1.1) to 5.1.N (5.1.2)
         125515 slanglois: MNT-16155 Update source headers - add new Copyrights for Java and JSP source files + automatic check in the build
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@127810 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
		
	
		
			
				
	
	
		
			314 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			314 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
/*
 | 
						|
 * #%L
 | 
						|
 * Alfresco Repository
 | 
						|
 * %%
 | 
						|
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 | 
						|
 * %%
 | 
						|
 * This file is part of the Alfresco software. 
 | 
						|
 * If the software was purchased under a paid Alfresco license, the terms of 
 | 
						|
 * the paid license agreement will prevail.  Otherwise, the software is 
 | 
						|
 * provided under the following open source license terms:
 | 
						|
 * 
 | 
						|
 * 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/>.
 | 
						|
 * #L%
 | 
						|
 */
 | 
						|
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;
 | 
						|
import javax.mail.Part;
 | 
						|
import javax.mail.internet.ContentType;
 | 
						|
import javax.mail.internet.MimeMessage;
 | 
						|
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;
 | 
						|
 
 | 
						|
/**
 | 
						|
 * Extract attachments according to provided AttachmentsExtractorMode
 | 
						|
 * 
 | 
						|
 * @since 3.4.7
 | 
						|
 */
 | 
						|
public class AttachmentsExtractor
 | 
						|
{
 | 
						|
   public static enum AttachmentsExtractorMode
 | 
						|
   {
 | 
						|
       /**
 | 
						|
         * Attachments will be extracted to the same folder where email lies.
 | 
						|
         */
 | 
						|
       SAME,
 | 
						|
       /**
 | 
						|
         * All attachments for all emails will be extracted to one folder.
 | 
						|
         */
 | 
						|
       COMMON,
 | 
						|
       /**
 | 
						|
         * All attachments for each email will be extracted to separate folder.
 | 
						|
         */
 | 
						|
       SEPARATE
 | 
						|
   }
 | 
						|
 
 | 
						|
   private Log logger = LogFactory.getLog(AttachmentsExtractor.class);
 | 
						|
 
 | 
						|
   private FileFolderService fileFolderService;
 | 
						|
   private NodeService nodeService;
 | 
						|
    private ImapService imapService;
 | 
						|
   private ServiceRegistry serviceRegistry;
 | 
						|
   private RepositoryFolderConfigBean attachmentsFolder;
 | 
						|
   private NodeRef attachmentsFolderRef;
 | 
						|
   private AttachmentsExtractorMode attachmentsExtractorMode;
 | 
						|
   private MimetypeService mimetypeService;
 | 
						|
 
 | 
						|
   public void setFileFolderService(FileFolderService fileFolderService)
 | 
						|
   {
 | 
						|
       this.fileFolderService = fileFolderService;
 | 
						|
   }
 | 
						|
 
 | 
						|
   public void setNodeService(NodeService nodeService)
 | 
						|
   {
 | 
						|
       this.nodeService = nodeService;
 | 
						|
    }
 | 
						|
 | 
						|
    public void setImapService(ImapService imapService)
 | 
						|
    {
 | 
						|
        this.imapService = imapService;
 | 
						|
   }
 | 
						|
 
 | 
						|
   public void setAttachmentsFolder(RepositoryFolderConfigBean attachmentsFolder)
 | 
						|
   {
 | 
						|
       this.attachmentsFolder = attachmentsFolder;
 | 
						|
   }
 | 
						|
 
 | 
						|
   public void setServiceRegistry(ServiceRegistry serviceRegistry)
 | 
						|
   {
 | 
						|
       this.serviceRegistry = serviceRegistry;
 | 
						|
   }
 | 
						|
 
 | 
						|
   public void setAttachmentsExtractorMode(String attachmentsExtractorMode)
 | 
						|
   {
 | 
						|
       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
 | 
						|
           {
 | 
						|
               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());
 | 
						|
   }
 | 
						|
 
 | 
						|
   public void extractAttachments(NodeRef messageRef, MimeMessage originalMessage) throws IOException, MessagingException
 | 
						|
   {
 | 
						|
       NodeRef attachmentsFolderRef = null;
 | 
						|
       String attachmentsFolderName = null;
 | 
						|
       boolean createFolder = false;
 | 
						|
       switch (attachmentsExtractorMode)
 | 
						|
       {
 | 
						|
       case SAME:
 | 
						|
           attachmentsFolderRef = nodeService.getPrimaryParent(messageRef).getParentRef();
 | 
						|
           break;
 | 
						|
       case COMMON:
 | 
						|
           attachmentsFolderRef = this.attachmentsFolderRef;
 | 
						|
           break;
 | 
						|
       case SEPARATE:
 | 
						|
       default:
 | 
						|
           String messageName = (String) nodeService.getProperty(messageRef, ContentModel.PROP_NAME);
 | 
						|
           attachmentsFolderName = messageName + "-attachments";
 | 
						|
           createFolder = true;
 | 
						|
           break;
 | 
						|
       }
 | 
						|
       if (!createFolder)
 | 
						|
       {
 | 
						|
           nodeService.createAssociation(messageRef, attachmentsFolderRef, ImapModel.ASSOC_IMAP_ATTACHMENTS_FOLDER);
 | 
						|
       }
 | 
						|
 
 | 
						|
       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 (createFolder)
 | 
						|
                   {
 | 
						|
                       attachmentsFolderRef = createAttachmentFolder(messageRef, attachmentsFolderName);
 | 
						|
                       createFolder = false;
 | 
						|
                   }
 | 
						|
                   createAttachment(messageRef, attachmentsFolderRef, part);
 | 
						|
               }
 | 
						|
           }
 | 
						|
       }
 | 
						|
 
 | 
						|
   }
 | 
						|
 
 | 
						|
    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 attachmentsFolderRef 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();
 | 
						|
       if (fileName == null || fileName.isEmpty())
 | 
						|
       {
 | 
						|
    	   fileName = "unnamed";
 | 
						|
       }
 | 
						|
       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(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);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        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);
 | 
						|
            
 | 
						|
                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);
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |