mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
EmailServer code.
- This is not fully integrated. In fact, the integration points have been disabled. - The main code for now is the remote stream. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6756 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
105
source/java/org/alfresco/email/server/impl/EmailMessageImpl.java
Normal file
105
source/java/org/alfresco/email/server/impl/EmailMessageImpl.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.email.server.impl;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.alfresco.service.cmr.email.EmailMessage;
|
||||
import org.alfresco.service.cmr.email.EmailMessagePart;
|
||||
|
||||
/**
|
||||
* Implementation EmailMessage interface.
|
||||
*
|
||||
* @author maxim
|
||||
* @since 2.2
|
||||
*/
|
||||
public class EmailMessageImpl implements EmailMessage
|
||||
{
|
||||
private static final long serialVersionUID = 8215537693963343756L;
|
||||
|
||||
private String to;
|
||||
private String from;
|
||||
private String subject;
|
||||
private Date sentDate;
|
||||
private EmailMessagePart body;
|
||||
|
||||
|
||||
public EmailMessageImpl(String to, String from, String subject, String body)
|
||||
{
|
||||
if (to == null)
|
||||
{
|
||||
throw new IllegalArgumentException("To cannot be null");
|
||||
}
|
||||
this.to = to;
|
||||
if (from == null)
|
||||
{
|
||||
throw new IllegalArgumentException("From cannot be null");
|
||||
}
|
||||
this.from = from;
|
||||
if (subject == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Subject cannot be null");
|
||||
}
|
||||
this.subject = subject;
|
||||
if (body == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Body cannot be null");
|
||||
}
|
||||
this.body = new EmailMessagePartImpl("Content.txt", body.getBytes());
|
||||
|
||||
this.sentDate = new Date();
|
||||
}
|
||||
|
||||
public String getTo()
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
public String getFrom()
|
||||
{
|
||||
return from;
|
||||
}
|
||||
|
||||
public String getSubject()
|
||||
{
|
||||
return subject;
|
||||
}
|
||||
|
||||
public Date getSentDate()
|
||||
{
|
||||
return sentDate;
|
||||
}
|
||||
|
||||
public EmailMessagePart getBody()
|
||||
{
|
||||
return body;
|
||||
}
|
||||
|
||||
public EmailMessagePart[] getAttachments()
|
||||
{
|
||||
return new EmailMessagePart[0];
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.email.server.impl;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.alfresco.service.cmr.email.EmailMessagePart;
|
||||
|
||||
/**
|
||||
* Implementation EmailMessagePart interface.
|
||||
*
|
||||
* @author maxim
|
||||
* @since 2.2
|
||||
*/
|
||||
public class EmailMessagePartImpl implements EmailMessagePart
|
||||
{
|
||||
private static final long serialVersionUID = 779186820993301580L;
|
||||
|
||||
private byte[] content;
|
||||
private String encoding;
|
||||
private String fileName;
|
||||
|
||||
|
||||
public EmailMessagePartImpl(String fileName, byte[] content)
|
||||
{
|
||||
this(fileName, null, content);
|
||||
}
|
||||
|
||||
public EmailMessagePartImpl(String fileName, String encoding, byte[] content)
|
||||
{
|
||||
if (fileName == null)
|
||||
{
|
||||
throw new IllegalArgumentException("FileName cannot be null");
|
||||
}
|
||||
this.fileName = fileName;
|
||||
|
||||
if (content == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Content cannot be null");
|
||||
}
|
||||
this.content = content;
|
||||
|
||||
if (encoding == null)
|
||||
{
|
||||
this.encoding = "utf8";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.encoding = encoding;
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream getContent()
|
||||
{
|
||||
return new ByteArrayInputStream(content);
|
||||
}
|
||||
|
||||
public String getContentType()
|
||||
{
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
public String getEncoding()
|
||||
{
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public String getFileName()
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return content.length;
|
||||
}
|
||||
}
|
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.email.server.impl.subetha;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Multipart;
|
||||
import javax.mail.Part;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.mail.internet.MimeUtility;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.service.cmr.email.EmailMessage;
|
||||
import org.alfresco.service.cmr.email.EmailMessageException;
|
||||
import org.alfresco.service.cmr.email.EmailMessagePart;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Concrete representation of an email message as implemented for the SubEtha mail server.
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
public class SubethaEmailMessage implements EmailMessage
|
||||
{
|
||||
private static final long serialVersionUID = -3735187524926395261L;
|
||||
|
||||
private static final Log log = LogFactory.getLog(SubethaEmailMessage.class);
|
||||
|
||||
private static final String MIME_PLAIN_TEXT = "text/plain";
|
||||
private static final String MIME_HTML_TEXT = "text/html";
|
||||
private static final String MIME_XML_TEXT = "text/xml";
|
||||
private static final String MIME_APPLICATION = "application/*";
|
||||
private static final String MIME_IMAGE = "image/*";
|
||||
private static final String MIME_MULTIPART = "multipart/*";
|
||||
private static final String MIME_RFC822 = "message/rfc822";
|
||||
private static final String FILENAME_ATTACHMENT_PREFIX = "Attachment";
|
||||
|
||||
private String from;
|
||||
private String to;
|
||||
private String subject;
|
||||
private Date sentDate;
|
||||
private EmailMessagePart body;
|
||||
private EmailMessagePart[] attachments;
|
||||
transient private int bodyNumber = 0;
|
||||
transient private int attachmentNumber = 0;
|
||||
transient private List<EmailMessagePart> attachmentList = new LinkedList<EmailMessagePart>();
|
||||
|
||||
protected SubethaEmailMessage()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public SubethaEmailMessage(MimeMessage mimeMessage)
|
||||
{
|
||||
processMimeMessage(mimeMessage);
|
||||
}
|
||||
|
||||
public SubethaEmailMessage(String from, String to, InputStream dataInputStream)
|
||||
{
|
||||
this.to = to;
|
||||
this.from = from;
|
||||
|
||||
MimeMessage mimeMessage = null;
|
||||
try
|
||||
{
|
||||
mimeMessage = new MimeMessage(Session.getDefaultInstance(System.getProperties()), dataInputStream);
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
throw new EmailMessageException(I18NUtil.getMessage("email.server.error-creating-message"), e);
|
||||
}
|
||||
|
||||
processMimeMessage(mimeMessage);
|
||||
}
|
||||
|
||||
private void processMimeMessage(MimeMessage mimeMessage)
|
||||
{
|
||||
if (from == null)
|
||||
{
|
||||
Address[] addresses = null;
|
||||
try
|
||||
{
|
||||
addresses = mimeMessage.getFrom();
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
throw new EmailMessageException("Error extract from.", e);
|
||||
}
|
||||
if (addresses == null || addresses.length == 0)
|
||||
{
|
||||
throw new EmailMessageException("There is no one from.");
|
||||
}
|
||||
from = addresses[0].toString();
|
||||
}
|
||||
|
||||
if (to == null)
|
||||
{
|
||||
Address[] addresses = null;
|
||||
try
|
||||
{
|
||||
addresses = mimeMessage.getAllRecipients();
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
throw new EmailMessageException("Error extract recepient.", e);
|
||||
}
|
||||
if (addresses == null || addresses.length == 0)
|
||||
{
|
||||
throw new EmailMessageException("There is no one recepient.");
|
||||
}
|
||||
to = addresses[0].toString();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
subject = mimeMessage.getSubject();
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
throw new EmailMessageException("Error extract subject.", e);
|
||||
}
|
||||
if (subject == null)
|
||||
{
|
||||
subject = ""; // Just anti-null stub :)
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
sentDate = mimeMessage.getSentDate();
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
throw new EmailMessageException("Error extract sentDate.", e);
|
||||
}
|
||||
if (sentDate == null)
|
||||
{
|
||||
sentDate = new Date(); // Just anti-null stub :)
|
||||
}
|
||||
|
||||
parseMesagePart(mimeMessage);
|
||||
attachments = new EmailMessagePart[attachmentList.size()];
|
||||
attachmentList.toArray(attachments);
|
||||
attachmentList = null;
|
||||
}
|
||||
|
||||
private void parseMesagePart(Part messagePart)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (messagePart.isMimeType(MIME_PLAIN_TEXT) || messagePart.isMimeType(MIME_HTML_TEXT))
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Text or HTML part was found. ContentType: " + messagePart.getContentType());
|
||||
}
|
||||
addBody(messagePart);
|
||||
}
|
||||
else if (messagePart.isMimeType(MIME_XML_TEXT))
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("XML part was found.");
|
||||
}
|
||||
addAttachment(messagePart);
|
||||
}
|
||||
else if (messagePart.isMimeType(MIME_APPLICATION))
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Application part was found.");
|
||||
}
|
||||
addAttachment(messagePart);
|
||||
}
|
||||
else if (messagePart.isMimeType(MIME_IMAGE))
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Image part was found.");
|
||||
}
|
||||
addAttachment(messagePart);
|
||||
}
|
||||
else if (messagePart.isMimeType(MIME_MULTIPART))
|
||||
{
|
||||
// if multipart, this method will be called recursively
|
||||
// for each of its parts
|
||||
Multipart mp = (Multipart) messagePart.getContent();
|
||||
int count = mp.getCount();
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("MULTIPART with " + count + " part(s) found. Processin each part...");
|
||||
}
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
parseMesagePart(mp.getBodyPart(i));
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("MULTIPART processed.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (messagePart.isMimeType(MIME_RFC822))
|
||||
{
|
||||
// if rfc822, call this method with its content as the part
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("MIME_RFC822 part found. Processing inside part...");
|
||||
}
|
||||
|
||||
parseMesagePart((Part) messagePart.getContent());
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("MIME_RFC822 processed.");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// if all else fails, put this in the attachments map.
|
||||
// Actually we don't know what it is.
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Unrecognized part was found. Put it into attachments.");
|
||||
}
|
||||
addAttachment(messagePart);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new EmailMessageException(I18NUtil.getMessage("email.server.error-parse-message"), e);
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
throw new EmailMessageException(I18NUtil.getMessage("email.server.error-parse-message"), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void addBody(Part messagePart) throws MessagingException
|
||||
{
|
||||
if (body != null)
|
||||
{
|
||||
if (!MIME_PLAIN_TEXT.equals(body.getContentType()) && messagePart.isMimeType(MIME_PLAIN_TEXT))
|
||||
{
|
||||
attachmentList.add(body);
|
||||
body = new SubethaEmailMessagePart(messagePart);
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Body has been changed to the new one.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attachmentList.add(new SubethaEmailMessagePart(messagePart, getPartFileName(getSubject() + " (part " + ++bodyNumber + ")", messagePart)));
|
||||
if (log.isInfoEnabled())
|
||||
{
|
||||
log.info(String.format("Attachment \"%s\" has been added.", attachmentList.get(attachmentList.size() - 1).getFileName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
body = new SubethaEmailMessagePart(messagePart, getPartFileName(getSubject() + " (part " + ++bodyNumber + ")", messagePart));
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Boby has been added.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method adds a message part to the attachments list
|
||||
*
|
||||
* @param messagePart A part of message
|
||||
* @throws EmailMessageException
|
||||
* @throws MessagingException
|
||||
*/
|
||||
private void addAttachment(Part messagePart) throws MessagingException
|
||||
{
|
||||
String fileName = getPartFileName(FILENAME_ATTACHMENT_PREFIX + ++attachmentNumber, messagePart);
|
||||
attachmentList.add(new SubethaEmailMessagePart(messagePart, fileName));
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Attachment added: " + fileName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method extracts file name from a message part for saving its as aa attachment. If the file name can't be extracted, it will be generated based on defaultPrefix parameter.
|
||||
*
|
||||
* @param defaultPrefix This prefix fill be used for generating file name.
|
||||
* @param messagePart A part of message
|
||||
* @return File name.
|
||||
* @throws MessagingException
|
||||
*/
|
||||
private String getPartFileName(String defaultPrefix, Part messagePart) throws MessagingException
|
||||
{
|
||||
String fileName = messagePart.getFileName();
|
||||
if (fileName != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
fileName = MimeUtility.decodeText(fileName);
|
||||
}
|
||||
catch (UnsupportedEncodingException ex)
|
||||
{
|
||||
// Nothing to do :)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName = defaultPrefix;
|
||||
if (messagePart.isMimeType(MIME_PLAIN_TEXT))
|
||||
fileName += ".txt";
|
||||
else if (messagePart.isMimeType(MIME_HTML_TEXT))
|
||||
fileName += ".html";
|
||||
else if (messagePart.isMimeType(MIME_XML_TEXT))
|
||||
fileName += ".xml";
|
||||
else if (messagePart.isMimeType(MIME_IMAGE))
|
||||
fileName += ".gif";
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setRmiRegistry(String rmiRegistryHost, int rmiRegistryPort)
|
||||
{
|
||||
if (body instanceof SubethaEmailMessagePart)
|
||||
{
|
||||
((SubethaEmailMessagePart) body).setRmiRegistry(rmiRegistryHost, rmiRegistryPort);
|
||||
}
|
||||
|
||||
for (EmailMessagePart attachment : attachments)
|
||||
{
|
||||
if (attachment instanceof SubethaEmailMessagePart) {
|
||||
((SubethaEmailMessagePart) attachment).setRmiRegistry(rmiRegistryHost, rmiRegistryPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getFrom()
|
||||
{
|
||||
return from;
|
||||
}
|
||||
|
||||
public String getTo()
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
public Date getSentDate()
|
||||
{
|
||||
return sentDate;
|
||||
}
|
||||
|
||||
public String getSubject()
|
||||
{
|
||||
return subject;
|
||||
}
|
||||
|
||||
public EmailMessagePart getBody()
|
||||
{
|
||||
return body;
|
||||
}
|
||||
|
||||
public EmailMessagePart[] getAttachments()
|
||||
{
|
||||
return attachments;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.email.server.impl.subetha;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Part;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.service.cmr.email.EmailMessageException;
|
||||
import org.alfresco.service.cmr.email.EmailMessagePart;
|
||||
import org.alfresco.util.remote.RemotableInputStream;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* @since 2.2
|
||||
*/
|
||||
public class SubethaEmailMessagePart implements EmailMessagePart
|
||||
{
|
||||
private static final long serialVersionUID = -8530238872199733096L;
|
||||
|
||||
static final Log log = LogFactory.getLog(SubethaEmailMessagePart.class);
|
||||
|
||||
private static final Pattern encodingExtractor = Pattern.compile("charset\\s*=[\\s\"]*([^\";\\s]*)");
|
||||
|
||||
private String encoding;
|
||||
private String fileName;
|
||||
private int fileSize = -1;
|
||||
private String contentType;
|
||||
private InputStream contentInputStream;
|
||||
|
||||
private String rmiRegistryHost;
|
||||
private int rmiRegistryPort;
|
||||
|
||||
protected SubethaEmailMessagePart()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Object can be built on existing message part only.
|
||||
*
|
||||
* @param messagePart Message part.
|
||||
*/
|
||||
public SubethaEmailMessagePart(Part messagePart)
|
||||
{
|
||||
if (messagePart == null)
|
||||
throw new IllegalArgumentException("messagePart");
|
||||
|
||||
try
|
||||
{
|
||||
fileSize = messagePart.getSize();
|
||||
fileName = messagePart.getFileName();
|
||||
contentType = messagePart.getContentType();
|
||||
|
||||
Matcher matcher = encodingExtractor.matcher(contentType);
|
||||
if (matcher.find())
|
||||
{
|
||||
encoding = matcher.group(1);
|
||||
if (!Charset.isSupported(encoding))
|
||||
{
|
||||
throw new EmailMessageException(I18NUtil.getMessage("email.server.usupported-encoding", encoding));
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
contentInputStream = messagePart.getInputStream();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new EmailMessageException(I18NUtil.getMessage("email.server.error-getting-content-stream"), ex);
|
||||
}
|
||||
}
|
||||
catch (MessagingException e)
|
||||
{
|
||||
throw new EmailMessageException(I18NUtil.getMessage("email.server.incorrect-message-part"), e);
|
||||
}
|
||||
}
|
||||
|
||||
public SubethaEmailMessagePart(Part messagePart, String fileName)
|
||||
{
|
||||
this(messagePart);
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
|
||||
public InputStream getContent()
|
||||
{
|
||||
return contentInputStream;
|
||||
}
|
||||
|
||||
public String getContentType()
|
||||
{
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public String getEncoding()
|
||||
{
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public String getFileName()
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
|
||||
public void setRmiRegistry(String rmiRegistryHost, int rmiRegistryPort)
|
||||
{
|
||||
this.rmiRegistryHost = rmiRegistryHost;
|
||||
this.rmiRegistryPort = rmiRegistryPort;
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException
|
||||
{
|
||||
contentInputStream = new RemotableInputStream(rmiRegistryHost, rmiRegistryPort, contentInputStream);
|
||||
out.defaultWriteObject();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
|
||||
{
|
||||
in.defaultReadObject();
|
||||
}
|
||||
}
|
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.email.server.impl.subetha;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.email.server.EmailServer;
|
||||
import org.alfresco.email.server.EmailServerConfiguration;
|
||||
import org.alfresco.service.cmr.email.EmailMessage;
|
||||
import org.alfresco.service.cmr.email.EmailMessageException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.subethamail.smtp.MessageContext;
|
||||
import org.subethamail.smtp.MessageHandler;
|
||||
import org.subethamail.smtp.MessageHandlerFactory;
|
||||
import org.subethamail.smtp.RejectException;
|
||||
import org.subethamail.smtp.TooMuchDataException;
|
||||
import org.subethamail.smtp.server.SMTPServer;
|
||||
import org.subethamail.smtp.server.io.DeferredFileOutputStream;
|
||||
|
||||
/**
|
||||
* @since 2.2
|
||||
*/
|
||||
public class SubethaEmailServer extends EmailServer
|
||||
{
|
||||
private final static Log log = LogFactory.getLog(SubethaEmailServer.class);
|
||||
|
||||
private SMTPServer serverImpl;
|
||||
|
||||
protected SubethaEmailServer(EmailServerConfiguration serverConfiguration)
|
||||
{
|
||||
super(serverConfiguration);
|
||||
serverImpl = new SMTPServer(new HandlerFactory());
|
||||
serverImpl.setPort(serverConfiguration.getPort());
|
||||
serverImpl.setHostName(serverConfiguration.getDomain());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startup()
|
||||
{
|
||||
serverImpl.start();
|
||||
log.info("Email Server has started successfully");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
serverImpl.stop();
|
||||
log.info("Email Server has stopped successfully");
|
||||
}
|
||||
|
||||
class HandlerFactory implements MessageHandlerFactory
|
||||
{
|
||||
public MessageHandler create(MessageContext messageContext)
|
||||
{
|
||||
return new Handler(messageContext);
|
||||
}
|
||||
};
|
||||
|
||||
class Handler implements MessageHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* 7 megs by default. The server will buffer incoming messages to disk when they hit this limit in the DATA received.
|
||||
*/
|
||||
private int DEFAULT_DATA_DEFERRED_SIZE = 1024 * 1024 * 7;
|
||||
|
||||
private List<String> EMPTY_LIST = new LinkedList<String>();
|
||||
|
||||
private String from;
|
||||
private MessageContext messageContext;
|
||||
List<Delivery> deliveries = new ArrayList<Delivery>();
|
||||
|
||||
public Handler(MessageContext messageContext)
|
||||
{
|
||||
this.messageContext = messageContext;
|
||||
}
|
||||
|
||||
public MessageContext getMessageContext()
|
||||
{
|
||||
return messageContext;
|
||||
}
|
||||
|
||||
public void from(String from) throws RejectException
|
||||
{
|
||||
this.from = from;
|
||||
try
|
||||
{
|
||||
blackAndWhiteListFiltering(from);
|
||||
}
|
||||
catch (EmailMessageException e)
|
||||
{
|
||||
throw new RejectException(554, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void recipient(String recipient) throws RejectException
|
||||
{
|
||||
deliveries.add(new Delivery(recipient));
|
||||
}
|
||||
|
||||
public void data(InputStream data) throws TooMuchDataException, IOException, RejectException
|
||||
{
|
||||
if (deliveries.size() == 1)
|
||||
{
|
||||
Delivery delivery = deliveries.get(0);
|
||||
processDelivery(delivery, data);
|
||||
}
|
||||
else if (deliveries.size() > 1)
|
||||
{
|
||||
DeferredFileOutputStream dfos = null;
|
||||
try
|
||||
{
|
||||
dfos = new DeferredFileOutputStream(DEFAULT_DATA_DEFERRED_SIZE);
|
||||
|
||||
byte[] bytes = new byte[1024 * 8];
|
||||
for (int len = -1; (len = data.read(bytes)) != -1;)
|
||||
{
|
||||
dfos.write(bytes, 0, len);
|
||||
}
|
||||
for (Delivery delivery : deliveries)
|
||||
{
|
||||
processDelivery(delivery, dfos.getInputStream());
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
dfos.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processDelivery(Delivery delivery, InputStream data) throws RejectException
|
||||
{
|
||||
EmailMessage emailMessage;
|
||||
try
|
||||
{
|
||||
emailMessage = new SubethaEmailMessage(from, delivery.getRecipient(), data);
|
||||
configuration.getEmailService().importMessage(emailMessage);
|
||||
}
|
||||
catch (EmailMessageException e)
|
||||
{
|
||||
throw new RejectException(554, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getAuthenticationMechanisms()
|
||||
{
|
||||
return EMPTY_LIST;
|
||||
}
|
||||
|
||||
public boolean auth(String clientInput, StringBuffer response) throws RejectException
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void resetState()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class Delivery
|
||||
{
|
||||
private String recipient;
|
||||
|
||||
public Delivery(String recipient)
|
||||
{
|
||||
this.recipient = recipient;
|
||||
}
|
||||
|
||||
public String getRecipient()
|
||||
{
|
||||
return recipient;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
Reference in New Issue
Block a user