ALF-6772 - IMAP: User metadata viewed in Outlook

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28848 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2011-07-07 13:11:06 +00:00
parent 6fdc7bb79f
commit a13c8cbf7e
7 changed files with 221 additions and 92 deletions

View File

@@ -11,4 +11,7 @@ imap.server.error.permission_denied = "Cannot create folder - Permission denied.
imap.server.error.folder_already_exist = "Folder already exists."
imap.server.error.mailbox_name_is_mandatory = "Mailbox name is mandatory parameter."
imap.server.error.cannot_get_a_folder = "Cannot get a folder with name ''{0}''."
imap.server.error.cannot_parse_default_email = "Cannot parse default e-mail address ''{0}''."

View File

@@ -162,6 +162,9 @@
<property name="defaultFromAddress">
<value>${imap.mail.from.default}</value>
</property>
<property name="defaultToAddress">
<value>${imap.mail.to.default}</value>
</property>
<property name="repositoryTemplatePath">
<value>${spaces.store}/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.imapConfig.childname}/${spaces.imap_templates.childname}</value>
</property>

View File

@@ -3,6 +3,7 @@ imap.server.port=143
imap.server.host=0.0.0.0
imap.mail.from.default=alfresco@demo.alfresco.org
imap.mail.to.default=alfresco@demo.alfresco.org
imap.config.home.store=${protocols.storeName}
imap.config.home.rootPath=${protocols.rootPath}

View File

@@ -55,11 +55,7 @@ import org.apache.commons.logging.LogFactory;
* @author Arseny Kovalchuk
*/
public abstract class AbstractMimeMessage extends MimeMessage
{
/** Used if imapHelper.getDefaultFromAddress is not set */
protected static final String DEFAULT_EMAIL_FROM = "alfresco@alfresco.org";
protected static final String DEFAULT_EMAIL_TO = DEFAULT_EMAIL_FROM;
{
protected static int MAX_RETRIES = 1;
private Log logger = LogFactory.getLog(AbstractMimeMessage.class);
@@ -133,53 +129,7 @@ public abstract class AbstractMimeMessage extends MimeMessage
// setHeader(X_ALF_SERVER_UID, imapService.getAlfrescoServerUID());
}
/**
* Builds the InternetAddress from the Content Author name if provided. If name not specified, it takes Content Creator name. If content creator does not exists, the default
* from address will be returned.
*
* @param contentAuthor The content author full name.
* @return Generated InternetAddress[] array.
* @throws AddressException
*/
protected InternetAddress[] buildSenderFromAddress() throws AddressException
{
// Generate FROM address (Content author)
InternetAddress[] addressList = null;
Map<QName, Serializable> properties = messageFileInfo.getProperties();
String prop = (String) properties.get(ContentModel.PROP_AUTHOR);
String defaultFromAddress = imapService.getDefaultFromAddress();
defaultFromAddress = defaultFromAddress == null ? DEFAULT_EMAIL_FROM : defaultFromAddress;
try
{
if (prop != null)
{
StringBuilder contentAuthor = new StringBuilder();
contentAuthor.append("\"").append(prop).append("\" <").append(defaultFromAddress).append(">");
addressList = InternetAddress.parse(contentAuthor.toString());
}
else
{
prop = (String) properties.get(ContentModel.PROP_CREATOR);
if (prop != null)
{
StringBuilder creator = new StringBuilder();
creator.append("\"").append(prop).append("\" <").append(defaultFromAddress).append(">");
addressList = InternetAddress.parse(creator.toString());
}
else
{
throw new AddressException(I18NUtil.getMessage("imap.server.error.properties_dont_exist"));
}
}
}
catch (AddressException e)
{
addressList = InternetAddress.parse(DEFAULT_EMAIL_FROM);
}
return addressList;
}
/**
* Returns {@link FileInfo} object representing message in Alfresco.
*
@@ -228,43 +178,7 @@ public abstract class AbstractMimeMessage extends MimeMessage
createEmailTemplateModel(messageFileInfo.getNodeRef()));
}
/**
* TODO USE CASE 2: "The To/addressee will be the first email alias found in the parent folders or a default one (TBD)".
* It seems to be more informative as alike {@code <user>@<current.domain>}...
*
* @return Generated TO address {@code <user>@<current.domain>}
* @throws AddressException
*/
protected InternetAddress[] buildRecipientToAddress() throws AddressException
{
InternetAddress[] result = null;
String defaultEmailTo = null;
final String escapedUserName = AuthenticationUtil.getFullyAuthenticatedUser().replaceAll("[/,\\,@]", ".");
final String userDomain = DEFAULT_EMAIL_TO.split("@")[1];
defaultEmailTo = escapedUserName + "@" + userDomain;
try
{
result = InternetAddress.parse(defaultEmailTo);
}
catch (AddressException e)
{
logger.error(String.format("Wrong email address '%s'.", defaultEmailTo), e);
result = InternetAddress.parse(DEFAULT_EMAIL_TO);
}
return result;
}
protected void addFromInternal(String addressesString) throws MessagingException
{
if (addressesString != null)
{
addFrom(InternetAddress.parse(addressesString));
}
else
{
addFrom(new Address[] { new InternetAddress(DEFAULT_EMAIL_FROM) });
}
}
/**
* Builds default email template model for TemplateProcessor
@@ -325,7 +239,5 @@ public abstract class AbstractMimeMessage extends MimeMessage
protected void updateMessageID() throws MessagingException
{
setHeader("Message-ID", this.messageFileInfo.getNodeRef().getId());
}
}
}

View File

@@ -25,7 +25,9 @@ import java.util.Map;
import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.AddressException;
import javax.mail.internet.ContentType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
@@ -33,12 +35,20 @@ import javax.mail.internet.MimeUtility;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.imap.ImapService.EmailBodyFormat;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
public class ContentModelMessage extends AbstractMimeMessage
{
private Log logger = LogFactory.getLog(ContentModelMessage.class);
protected static final String DEFAULT_EMAIL_FROM = "alfresco@alfresco.org";
protected static final String DEFAULT_EMAIL_TO = "alfresco@alfresco.org";
public ContentModelMessage(FileInfo fileInfo, ServiceRegistry serviceRegistry, boolean generateBody) throws MessagingException
{
@@ -143,6 +153,163 @@ public class ContentModelMessage extends AbstractMimeMessage
return s.toString();
}
}
/**
* Generate the "to" address.
*
* Step 1: Use PROP_ADDRESSEE
*
* Last Step: Use the default address
*
* @return Generated TO address {@code <user>@<current.domain>}
* @throws AddressException
*/
private InternetAddress[] buildRecipientToAddress() throws AddressException
{
InternetAddress[] result = null;
Map<QName, Serializable> properties = messageFileInfo.getProperties();
/**
* Step 1 : Get the ADDRESSEE if it exists
*/
if(properties.containsKey(ContentModel.PROP_ADDRESSEE))
{
String addressee = (String)properties.get(ContentModel.PROP_ADDRESSEE);
try
{
result = InternetAddress.parse(addressee);
return result;
}
catch (AddressException e)
{
// try next step
}
}
// final String escapedUserName = AuthenticationUtil.getFullyAuthenticatedUser().replaceAll("[/,\\,@]", ".");
// final String userDomain = DEFAULT_EMAIL_TO.split("@")[1];
// String userName = escapedUserName + "@" + userDomain;
// try
// {
// result = InternetAddress.parse(userName);
// return result;
// }
// catch (AddressException e)
// {
// }
/**
* Last Step : Get the Default address
*/
String defaultToAddress = imapService.getDefaultToAddress();
try
{
result = InternetAddress.parse(defaultToAddress);
return result;
}
catch (AddressException e)
{
logger.warn(String.format("Wrong email address '%s'.", defaultToAddress), e);
}
result = InternetAddress.parse(DEFAULT_EMAIL_TO);
return result;
}
/**
* Builds the InternetAddress for the sender (from)
*
* Step 1: use PROP_ORIGINATOR
*
* Last Step : Use the default address.
*
* Content Author name if provided. If name not specified, it takes Content Creator name.
* If content creator does not exists, the default from address will be returned.
*
* @param contentAuthor The content author full name.
* @return Generated InternetAddress[] array.
* @throws AddressException
*/
private InternetAddress[] buildSenderFromAddress() throws AddressException
{
// Generate FROM address (Content author)
InternetAddress[] result = null;
Map<QName, Serializable> properties = messageFileInfo.getProperties();
String defaultFromAddress = imapService.getDefaultFromAddress();
/**
* Step 1 : Get the ORIGINATOR if it exists
*/
if(properties.containsKey(ContentModel.PROP_ORIGINATOR))
{
String addressee = (String)properties.get(ContentModel.PROP_ORIGINATOR);
try
{
result = InternetAddress.parse(addressee);
return result;
}
catch (AddressException e)
{
// try next step
}
}
/**
* Go for the author property
*/
if(properties.containsKey(ContentModel.PROP_AUTHOR))
{
String author = (String) properties.get(ContentModel.PROP_AUTHOR);
try
{
StringBuilder contentAuthor = new StringBuilder();
contentAuthor.append("\"").append(author).append("\" <").append(defaultFromAddress).append(">");
result = InternetAddress.parse(contentAuthor.toString());
return result;
}
catch (AddressException e)
{
// try next step
}
}
if(properties.containsKey(ContentModel.PROP_CREATOR))
{
String author = (String) properties.get(ContentModel.PROP_CREATOR);
try
{
StringBuilder contentAuthor = new StringBuilder();
contentAuthor.append("\"").append(author).append("\" <").append(defaultFromAddress).append(">");
result = InternetAddress.parse(contentAuthor.toString());
return result;
}
catch (AddressException e)
{
// try next step
}
}
/**
* Last Step : Get the Default address
*/
try
{
result = InternetAddress.parse(defaultFromAddress);
return result;
}
catch (AddressException e)
{
logger.warn(String.format("Wrong email address '%s'.", defaultFromAddress), e);
}
result = InternetAddress.parse(DEFAULT_EMAIL_FROM);
return result;
}
}

View File

@@ -228,6 +228,11 @@ public interface ImapService
* @return Default From addreses
*/
public String getDefaultFromAddress();
/**
* @return Default To addreses
*/
public String getDefaultToAddress();
/**
* @return Path to the folder containing templates, that will be used for generating body of message in VIRTUAL and MIXED views.

View File

@@ -20,6 +20,8 @@ package org.alfresco.repo.imap;
import static org.alfresco.repo.imap.AlfrescoImapConst.DICTIONARY_TEMPLATE_PREFIX;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -111,7 +113,8 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol
private static final String ERROR_FOLDER_ALREADY_EXISTS = "imap.server.error.folder_already_exist";
private static final String ERROR_MAILBOX_NAME_IS_MANDATORY = "imap.server.error.mailbox_name_is_mandatory";
private static final String ERROR_CANNOT_GET_A_FOLDER = "imap.server.error.cannot_get_a_folder";
private static final String ERROR_CANNOT_PARSE_DEFAULT_EMAIL = "imap.server.error.cannot_parse_default_email";
private static final String CHECKED_NODES = "imap.flaggable.aspect.checked.list";
private static final String FAVORITE_SITES = "imap.favorite.sites.list";
private static final String UIDVALIDITY_LISTENER_ALREADY_BOUND = "imap.uidvalidity.already.bound";
@@ -139,6 +142,7 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol
private Set<NodeRef> ignoreExtractionFolders;
private String defaultFromAddress;
private String defaultToAddress;
private String repositoryTemplatePath;
private boolean extractAttachmentsEnabled = true;
@@ -261,6 +265,16 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol
{
this.defaultFromAddress = defaultFromAddress;
}
public String getDefaultToAddress()
{
return defaultToAddress;
}
public void setDefaultToAddress(String defaultToAddress)
{
this.defaultToAddress = defaultToAddress;
}
public String getWebApplicationContextUrl()
{
@@ -324,9 +338,33 @@ public class ImapServiceImpl implements ImapService, OnCreateChildAssociationPol
PropertyCheck.mandatory(this, "permissionService", permissionService);
PropertyCheck.mandatory(this, "serviceRegistry", serviceRegistry);
PropertyCheck.mandatory(this, "defaultFromAddress", defaultFromAddress);
PropertyCheck.mandatory(this, "defaultToAddress", defaultToAddress);
PropertyCheck.mandatory(this, "repositoryTemplatePath", repositoryTemplatePath);
PropertyCheck.mandatory(this, "policyBehaviourFilter", policyBehaviourFilter);
PropertyCheck.mandatory(this, "mimetypeService", mimetypeService);
// be sure that a default e-mail is correct
try
{
InternetAddress.parse(defaultFromAddress);
}
catch (AddressException ex)
{
throw new AlfrescoRuntimeException(
ERROR_CANNOT_PARSE_DEFAULT_EMAIL,
new Object[] {defaultFromAddress});
}
try
{
InternetAddress.parse(defaultToAddress);
}
catch (AddressException ex)
{
throw new AlfrescoRuntimeException(
ERROR_CANNOT_PARSE_DEFAULT_EMAIL,
new Object[] {defaultToAddress});
}
}
public void startup()