/* * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.integration.mail.config; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Session; import javax.mail.URLName; import javax.mail.internet.MimeMessage; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.expression.Expression; import org.springframework.integration.mail.AbstractMailReceiver; import org.springframework.integration.mail.ImapMailReceiver; import org.springframework.integration.mail.MailReceiver; import org.springframework.integration.mail.Pop3MailReceiver; import org.springframework.integration.mail.SearchTermStrategy; import org.springframework.integration.mapping.HeaderMapper; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * @author Mark Fisher * @author Oleg Zhurakousky * @author Gary Russell * @since 1.0.3 */ public class MailReceiverFactoryBean implements FactoryBean<MailReceiver>, DisposableBean, BeanFactoryAware { protected final Log logger = LogFactory.getLog(this.getClass()); private volatile String storeUri; private volatile String protocol; private volatile Session session; private volatile MailReceiver receiver; private volatile Properties javaMailProperties; private volatile Authenticator authenticator; /** * Indicates whether retrieved messages should be deleted from the server. * This value will be <code>null</code> <i>unless</i> explicitly configured. */ private volatile Boolean shouldDeleteMessages = null; private volatile Boolean shouldMarkMessagesAsRead = null; private volatile int maxFetchSize = 1; private volatile Expression selectorExpression; private volatile SearchTermStrategy searchTermStrategy; private volatile String userFlag; private volatile BeanFactory beanFactory; private volatile HeaderMapper<MimeMessage> headerMapper; private Boolean embeddedPartsAsBytes; private Boolean simpleContent; public void setStoreUri(String storeUri) { this.storeUri = storeUri; } public void setProtocol(String protocol) { this.protocol = protocol; } public void setSession(Session session) { this.session = session; } public void setJavaMailProperties(Properties javaMailProperties) { this.javaMailProperties = javaMailProperties; } public void setAuthenticator(Authenticator authenticator) { this.authenticator = authenticator; } public void setShouldDeleteMessages(Boolean shouldDeleteMessages) { this.shouldDeleteMessages = shouldDeleteMessages; } public void setShouldMarkMessagesAsRead(Boolean shouldMarkMessagesAsRead) { this.shouldMarkMessagesAsRead = shouldMarkMessagesAsRead; } public Boolean isShouldMarkMessagesAsRead() { return this.shouldMarkMessagesAsRead != null && this.shouldMarkMessagesAsRead; } public void setMaxFetchSize(int maxFetchSize) { this.maxFetchSize = maxFetchSize; } public void setSelectorExpression(Expression selectorExpression) { this.selectorExpression = selectorExpression; } public void setSearchTermStrategy(SearchTermStrategy searchTermStrategy) { this.searchTermStrategy = searchTermStrategy; } public void setUserFlag(String userFlag) { this.userFlag = userFlag; } public void setHeaderMapper(HeaderMapper<MimeMessage> headerMapper) { this.headerMapper = headerMapper; } public void setEmbeddedPartsAsBytes(Boolean embeddedPartsAsBytes) { this.embeddedPartsAsBytes = embeddedPartsAsBytes; } public void setSimpleContent(Boolean simpleContent) { this.simpleContent = simpleContent; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } @Override public MailReceiver getObject() throws Exception { if (this.receiver == null) { this.receiver = this.createReceiver(); } return this.receiver; } @Override public Class<?> getObjectType() { return (this.receiver != null) ? this.receiver.getClass() : MailReceiver.class; } @Override public boolean isSingleton() { return true; } private void verifyProtocol() { if (StringUtils.hasText(this.storeUri)) { URLName urlName = new URLName(this.storeUri); if (this.protocol == null) { this.protocol = urlName.getProtocol(); } else { Assert.isTrue(this.protocol.equals(urlName.getProtocol()), "The provided 'protocol' does not match that in the 'storeUri'."); } } else { Assert.hasText(this.protocol, "Either the 'storeUri' or 'protocol' is required."); } Assert.hasText(this.protocol, "Unable to resolve protocol."); } private MailReceiver createReceiver() { this.verifyProtocol(); boolean isPop3 = this.protocol.toLowerCase().startsWith("pop3"); boolean isImap = this.protocol.toLowerCase().startsWith("imap"); Assert.isTrue(isPop3 || isImap, "the store URI must begin with 'pop3' or 'imap'"); AbstractMailReceiver receiver = isPop3 ? new Pop3MailReceiver(this.storeUri) : new ImapMailReceiver(this.storeUri); if (this.session != null) { Assert.isNull(this.javaMailProperties, "JavaMail Properties are not allowed when a Session has been provided."); Assert.isNull(this.authenticator, "A JavaMail Authenticator is not allowed when a Session has been provided."); receiver.setSession(this.session); } if (this.searchTermStrategy != null) { Assert.isTrue(isImap, "searchTermStrategy is only allowed with imap"); ((ImapMailReceiver) receiver).setSearchTermStrategy(this.searchTermStrategy); } if (this.javaMailProperties != null) { receiver.setJavaMailProperties(this.javaMailProperties); } if (this.authenticator != null) { receiver.setJavaMailAuthenticator(this.authenticator); } if (this.shouldDeleteMessages != null) { // always set the value if configured explicitly // otherwise, the default is true for POP3 but false for IMAP receiver.setShouldDeleteMessages(this.shouldDeleteMessages); } receiver.setMaxFetchSize(this.maxFetchSize); receiver.setSelectorExpression(this.selectorExpression); if (StringUtils.hasText(this.userFlag)) { receiver.setUserFlag(this.userFlag); } if (isPop3) { if (this.isShouldMarkMessagesAsRead() && this.logger.isWarnEnabled()) { this.logger.warn("Setting 'should-mark-messages-as-read' to 'true' while using POP3 has no effect"); } } else if (isImap) { ((ImapMailReceiver) receiver).setShouldMarkMessagesAsRead(this.shouldMarkMessagesAsRead); } if (this.beanFactory != null) { receiver.setBeanFactory(this.beanFactory); } if (this.headerMapper != null) { receiver.setHeaderMapper(this.headerMapper); } if (this.embeddedPartsAsBytes != null) { receiver.setEmbeddedPartsAsBytes(this.embeddedPartsAsBytes); } if (this.simpleContent != null) { receiver.setSimpleContent(this.simpleContent); } receiver.afterPropertiesSet(); return receiver; } @Override public void destroy() throws Exception { if (this.receiver != null && this.receiver instanceof DisposableBean) { ((DisposableBean) this.receiver).destroy(); } } }