com.mgmtp.jfunk.core.mail.EmailModule.java Source code

Java tutorial

Introduction

Here is the source code for com.mgmtp.jfunk.core.mail.EmailModule.java

Source

/*
 * Copyright (c) 2015 mgm technology partners GmbH
 *
 * 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 com.mgmtp.jfunk.core.mail;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.Maps.filterKeys;
import static com.google.common.collect.Sets.newHashSet;
import static com.mgmtp.jfunk.common.util.Predicates.contains;
import static com.mgmtp.jfunk.core.mail.EmailConstants.MAIL_DEBUG;
import static com.mgmtp.jfunk.core.mail.EmailConstants.MAIL_DELETE_ALL_ON_RESERVATION;
import static com.mgmtp.jfunk.core.mail.EmailConstants.MAIL_SLEEP_MILLIS;
import static com.mgmtp.jfunk.core.mail.EmailConstants.MAIL_SSL_TRUST;
import static com.mgmtp.jfunk.core.mail.EmailConstants.MAIL_STORE_PROTOCOL;
import static com.mgmtp.jfunk.core.mail.EmailConstants.MAIL_TIMEOUT_SECONDS;
import static com.mgmtp.jfunk.core.mail.EmailConstants.MAIL_TRANSPORT_PROTOCOL;
import static java.lang.String.format;
import static org.apache.commons.lang3.StringUtils.substringAfterLast;
import static org.apache.commons.lang3.StringUtils.substringBeforeLast;

import java.security.GeneralSecurityException;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.inject.Singleton;
import javax.mail.Session;

import org.apache.commons.lang3.mutable.MutableInt;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Table;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.mgmtp.jfunk.common.config.ModuleScoped;
import com.mgmtp.jfunk.common.config.ScriptScoped;
import com.mgmtp.jfunk.common.util.Configuration;
import com.mgmtp.jfunk.core.config.BaseJFunkGuiceModule;
import com.mgmtp.jfunk.core.mail.StoreManager.FileMessageWrapper;
import com.sun.mail.util.MailSSLSocketFactory;

/**
 * Guice module for e-mail handling. This module must be installed when e-mail support is necessary.
 * 
 * @author rnaegele
 */
public class EmailModule extends BaseJFunkGuiceModule {

    private static final Pattern MAIL_ACCOUNT_START_PATTERN = Pattern.compile("mail[.]pool[.]([^.]+)[.].*");
    private static final Pattern MAIL_ACCOUNT_END_PATTERN = Pattern.compile("user|password|address");
    private static final String MAIL_USER_KEY_TEMPLATE = "${mail.pool.%s.%s.user,%s}";
    private static final String MAIL_PASSWORD_KEY_TEMPLATE = "${mail.pool.%s.%s.password,${mail.default.password}}";
    private static final String MAIL_ADDRESS_KEY_TEMPLATE = "${mail.pool.%s.%s.address,%s@${mail.default.domain}}";

    @Override
    protected void doConfigure() {
        bind(MailService.class);
        bind(MailAccountManager.class);
        bind(SmtpClient.class);

        install(new PrivateModule() {
            @Override
            protected void configure() {
                bind(MutableInt.class).in(ModuleScoped.class);
                bind(MailArchiver.class);
                // expose only MailArchiver
                expose(MailArchiver.class);
            }
        });

        install(new FactoryModuleBuilder().build(StoreManager.Factory.class));
        bindEventHandler().to(MailboxPurger.class);
        bindEventHandler().to(MailAccountReleaser.class);
    }

    @Provides
    @StoreSession
    Properties provideStoreSession(final Configuration config) throws GeneralSecurityException {
        String protocol = checkNotNull(config.get(MAIL_STORE_PROTOCOL), "Property %s not configured.",
                MAIL_STORE_PROTOCOL);
        Properties sessionProps = new Properties();
        sessionProps.putAll(filterKeys(config, contains('.' + protocol + '.')));
        sessionProps.setProperty(MAIL_DEBUG, config.get(MAIL_DEBUG, "false"));
        sessionProps.setProperty(MAIL_STORE_PROTOCOL, protocol);

        if (config.getBoolean(MAIL_SSL_TRUST)) {
            MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();
            socketFactory.setTrustAllHosts(true);
            sessionProps.put("mail." + protocol + ".ssl.socketFactory", socketFactory);
        }

        return sessionProps;
    }

    @Provides
    @TransportSession
    Session provideTransportSession(final Configuration config) throws GeneralSecurityException {
        String protocol = checkNotNull(config.get(MAIL_TRANSPORT_PROTOCOL), "Property %s not configured.",
                MAIL_TRANSPORT_PROTOCOL);
        Properties sessionProps = new Properties();
        sessionProps.putAll(filterKeys(config, contains('.' + protocol + '.')));
        sessionProps.setProperty(MAIL_DEBUG, config.get(MAIL_DEBUG, "false"));
        sessionProps.setProperty(MAIL_TRANSPORT_PROTOCOL, protocol);

        String user = config.get("mail." + protocol + ".user");
        String password = config.get("mail." + protocol + ".password");

        if (config.getBoolean("mail.ssl.trust")) {
            MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();
            socketFactory.setTrustAllHosts(true);
            sessionProps.put("mail." + protocol + ".ssl.socketFactory", socketFactory);
        }
        return !isNullOrEmpty(user) && !isNullOrEmpty(password)
                ? Session.getInstance(sessionProps, new MailAuthenticator(user, password))
                : Session.getInstance(sessionProps);
    }

    @Provides
    @MailFolder
    String provideMailFolder(final Configuration config) {
        String protocol = checkNotNull(config.get(MAIL_STORE_PROTOCOL), "Property %s not configured.",
                MAIL_STORE_PROTOCOL);
        return config.get("mail." + protocol + ".folder", "INBOX");
    }

    @Provides
    @MailTimeoutSeconds
    long provideMailTimeoutSeconds(final Configuration config) {
        return config.getLong(MAIL_TIMEOUT_SECONDS, 60);
    }

    @Provides
    @MailSleepMillis
    long provideMailSleepMillis(final Configuration config) {
        return config.getLong(MAIL_SLEEP_MILLIS, 5000);
    }

    @Provides
    @MailDeleteOnReservation
    boolean provideMailDeleteOnStartup(final Configuration config) {
        return config.getBoolean(MAIL_DELETE_ALL_ON_RESERVATION, true);
    }

    @Provides
    @Singleton
    SetMultimap<String, MailAccount> provideEmailAddressPools(final Configuration config) {
        SetMultimap<String, MailAccount> result = HashMultimap.create();
        Set<String> accountIdCache = newHashSet();

        for (Entry<String, String> entry : config.entrySet()) {
            String key = entry.getKey();

            Matcher matcher = MAIL_ACCOUNT_START_PATTERN.matcher(key);
            if (matcher.matches()) {
                String pool = matcher.group(1);
                String suffix = substringAfterLast(key, pool + '.');

                matcher = MAIL_ACCOUNT_END_PATTERN.matcher(suffix);
                String accountId = matcher.find() ? substringBeforeLast(suffix, ".") : suffix;

                if (accountIdCache.contains(accountId)) {
                    continue;
                }

                accountIdCache.add(accountId);

                String user = config
                        .processPropertyValue(format(MAIL_USER_KEY_TEMPLATE, pool, accountId, accountId));
                String password = config.processPropertyValue(format(MAIL_PASSWORD_KEY_TEMPLATE, pool, accountId));
                String address = config
                        .processPropertyValue(format(MAIL_ADDRESS_KEY_TEMPLATE, pool, accountId, accountId));

                result.put(pool, new MailAccount(accountId, address, user, password));
            }
        }

        return result;
    }

    @Provides
    @ScriptScoped
    Table<String, String, FileMessageWrapper> provideMailMessageCache() {
        return HashBasedTable.create();
    }
}