/* * Copyright 2014-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.dsl; import java.util.Collection; import java.util.Collections; import java.util.Properties; import java.util.function.Consumer; import java.util.function.Function; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.Part; import javax.mail.Session; import javax.mail.internet.MimeMessage; import org.springframework.expression.Expression; import org.springframework.integration.dsl.ComponentsRegistration; import org.springframework.integration.dsl.MessageSourceSpec; import org.springframework.integration.expression.FunctionExpression; import org.springframework.integration.mail.AbstractMailReceiver; import org.springframework.integration.mail.MailReceivingMessageSource; import org.springframework.integration.mapping.HeaderMapper; import org.springframework.integration.support.PropertiesBuilder; import org.springframework.util.Assert; /** * A {@link MessageSourceSpec} for a {@link MailReceivingMessageSource}. * * * @param <S> the target {@link MailInboundChannelAdapterSpec} implementation type. * @param <R> the target {@link AbstractMailReceiver} implementation type. * * @author Gary Russell * @author Artem Bilan * @since 5.0 */ public abstract class MailInboundChannelAdapterSpec<S extends MailInboundChannelAdapterSpec<S, R>, R extends AbstractMailReceiver> extends MessageSourceSpec<S, MailReceivingMessageSource> implements ComponentsRegistration { protected final R receiver; protected final boolean externalReceiver; private boolean sessionProvided; protected MailInboundChannelAdapterSpec(R receiver) { this(receiver, false); } protected MailInboundChannelAdapterSpec(R receiver, boolean externalReceiver) { this.receiver = receiver; this.externalReceiver = externalReceiver; } /** * Configure a SpEL expression to select messages. The root object for the expression * evaluation is a {@link javax.mail.internet.MimeMessage} which should return a boolean * result (true means select the message). * @param selectorExpression the selectorExpression. * @return the spec. */ public S selectorExpression(String selectorExpression) { assertReceiver(); this.receiver.setSelectorExpression(PARSER.parseExpression(selectorExpression)); return _this(); } protected void assertReceiver() { Assert.state(!this.externalReceiver, "An external 'receiver' [" + this.receiver + "] can't be modified."); } /** * Configure a SpEL expression to select messages. The root object for the expression * evaluation is a {@link javax.mail.internet.MimeMessage} which should return a boolean * result (true means select the message). * @param selectorExpression the selectorExpression. * @return the spec. */ public S selectorExpression(Expression selectorExpression) { assertReceiver(); this.receiver.setSelectorExpression(selectorExpression); return _this(); } /** * Configure a {@link Function} to select messages. The argument for the function * is a {@link javax.mail.internet.MimeMessage}; {@code apply} returns a boolean * result (true means select the message). * @param selectorFunction the selectorFunction. * @return the spec. * @see FunctionExpression */ public S selector(Function<MimeMessage, Boolean> selectorFunction) { assertReceiver(); this.receiver.setSelectorExpression(new FunctionExpression<MimeMessage>(selectorFunction)); return _this(); } /** * Provide the Java Mail {@link Session} to use. * @param session the session. * @return the spec. * @see AbstractMailReceiver#setSession(Session) */ public S session(Session session) { assertReceiver(); this.receiver.setSession(session); this.sessionProvided = true; return _this(); } /** * The Java Mail properties. * @param javaMailProperties the javaMailProperties. * @return the spec. * @see AbstractMailReceiver#setJavaMailProperties(Properties) */ public S javaMailProperties(Properties javaMailProperties) { assertReceiver(); assertSession(); this.receiver.setJavaMailProperties(javaMailProperties); return _this(); } private void assertSession() { Assert.state(!this.sessionProvided, "Neither 'javaMailProperties' nor 'javaMailAuthenticator' " + "references are allowed when a 'session' reference has been provided."); } /** * Configure the {@code javaMailProperties} by invoking a {@link Consumer} callback which * is invoked with a {@link PropertiesBuilder}. * @param configurer the configurer. * @return the spec. * @see AbstractMailReceiver#setJavaMailProperties(Properties) */ public S javaMailProperties(Consumer<PropertiesBuilder> configurer) { PropertiesBuilder properties = new PropertiesBuilder(); configurer.accept(properties); return javaMailProperties(properties.get()); } /** * The Java Mail {@link Authenticator}. * @param javaMailAuthenticator the javaMailAuthenticator. * @return the spec. * @see AbstractMailReceiver#setJavaMailAuthenticator(Authenticator) */ public S javaMailAuthenticator(Authenticator javaMailAuthenticator) { assertSession(); assertReceiver(); this.receiver.setJavaMailAuthenticator(javaMailAuthenticator); return _this(); } /** * The maximum for fetch size. * @param maxFetchSize the maxFetchSize. * @return the spec. * @see AbstractMailReceiver#setMaxFetchSize(int) */ public S maxFetchSize(int maxFetchSize) { assertReceiver(); this.receiver.setMaxFetchSize(maxFetchSize); return _this(); } /** * A flag to specify if messages should be deleted after receive. * @param shouldDeleteMessages the shouldDeleteMessages. * @return the spec. * @see AbstractMailReceiver#setShouldDeleteMessages(boolean) */ public S shouldDeleteMessages(boolean shouldDeleteMessages) { assertReceiver(); this.receiver.setShouldDeleteMessages(shouldDeleteMessages); return _this(); } /** * Set the name of the flag to use to flag messages when the server does * not support \Recent but supports user flags; * default {@value AbstractMailReceiver#DEFAULT_SI_USER_FLAG}. * @param userFlag the flag. * @return the spec. * @see AbstractMailReceiver#setUserFlag(String) */ public S userFlag(String userFlag) { assertReceiver(); this.receiver.setUserFlag(userFlag); return _this(); } /** * Set the header mapper; if a header mapper is not provided, the message payload is * a {@link MimeMessage}, when provided, the headers are mapped and the payload is * the {@link MimeMessage} content. * @param headerMapper the header mapper. * @return the spec. * @see AbstractMailReceiver#setUserFlag(String) * @see #embeddedPartsAsBytes(boolean) */ public S headerMapper(HeaderMapper<MimeMessage> headerMapper) { assertReceiver(); this.receiver.setHeaderMapper(headerMapper); return _this(); } /** * When a header mapper is provided determine whether an embedded {@link Part} (e.g * {@link Message} or {@link javax.mail.Multipart} content is rendered as a byte[] in the * payload. Otherwise, leave as a {@link Part}. These objects are not suitable for * downstream serialization. Default: true. * <p>This has no effect if there is no header mapper, in that case the payload is the * {@link MimeMessage}. * @param embeddedPartsAsBytes the embeddedPartsAsBytes to set. * @return the spec. * @see #headerMapper(HeaderMapper) */ public S embeddedPartsAsBytes(boolean embeddedPartsAsBytes) { assertReceiver(); this.receiver.setEmbeddedPartsAsBytes(embeddedPartsAsBytes); return _this(); } /** * Determine how the content is rendered. * @param simpleContent true for simple content. * @return the spec. * @see AbstractMailReceiver#setSimpleContent(boolean) */ public S simpleContent(boolean simpleContent) { assertReceiver(); this.receiver.setSimpleContent(simpleContent); return _this(); } @Override public Collection<Object> getComponentsToRegister() { return Collections.<Object>singletonList(this.receiver); } @Override public MailReceivingMessageSource doGet() { return new MailReceivingMessageSource(this.receiver); } }