/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. */ package com.liferay.mail.reader.internal.imap; import com.liferay.mail.reader.configuration.MailGroupServiceConfiguration; import com.liferay.mail.reader.exception.MailException; import com.liferay.mail.reader.model.Account; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.module.configuration.ConfigurationException; import com.liferay.portal.kernel.module.configuration.ConfigurationProviderUtil; import com.liferay.portal.kernel.util.PortalUtil; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Store; import javax.mail.Transport; import javax.net.ssl.SSLSocketFactory; import org.apache.commons.lang.time.StopWatch; /** * @author Scott Lee */ public class IMAPConnection { public IMAPConnection(Account account, String password) { this( account.getIncomingHostName(), account.getIncomingPort(), account.getIncomingSecure(), account.getOutgoingHostName(), account.getOutgoingPort(), account.getOutgoingSecure(), account.getLogin(), password); } public IMAPConnection( String incomingHostName, int incomingPort, boolean incomingSecure, String outgoingHostName, int outgoingPort, boolean outgoingSecure, String login, String password) { _incomingHostName = incomingHostName; _incomingPort = incomingPort; _incomingSecure = incomingSecure; _outgoingHostName = outgoingHostName; _outgoingPort = outgoingPort; _outgoingSecure = outgoingSecure; _login = login; _password = password; } public Session getSession() { if (_session != null) { return _session; } Properties properties = new Properties(); properties.put("mail.debug", String.valueOf(isJavaMailDebug())); properties.put("mail.imap.host", _incomingHostName); properties.put("mail.imap.port", _incomingPort); properties.put("mail.imaps.auth", "true"); properties.put("mail.imaps.host", _incomingHostName); properties.put("mail.imaps.port", _incomingPort); properties.put( "mail.imaps.socketFactory.class", SSLSocketFactory.class.getName()); properties.put("mail.imaps.socketFactory.fallback", "false"); properties.put("mail.imaps.socketFactory.port", _incomingPort); properties.put("mail.smtp.host", _outgoingHostName); properties.put("mail.smtp.port", _outgoingPort); properties.put("mail.smtps.auth", "true"); properties.put("mail.smtps.host", _outgoingHostName); properties.put("mail.smtps.port", _outgoingPort); properties.put( "mail.smtps.socketFactory.class", SSLSocketFactory.class.getName()); properties.put("mail.smtps.socketFactory.fallback", "false"); properties.put("mail.smtps.socketFactory.port", _outgoingPort); _session = Session.getInstance(properties); _session.setDebug(isJavaMailDebug()); return _session; } public Store getStore(boolean useOldStores) throws MailException { Store store = null; try { String storeKey = _incomingHostName.concat( _outgoingHostName).concat(_login); if (useOldStores) { store = _allStores.get(storeKey); if ((store != null) && !store.isConnected()) { store.close(); store = null; } } if (store == null) { Session session = getSession(); if (_incomingSecure) { store = session.getStore("imaps"); } else { store = session.getStore("imap"); } store.connect( _incomingHostName, _incomingPort, _login, _password); if (useOldStores) { _allStores.put(storeKey, store); } } return store; } catch (MessagingException me) { throw new MailException( MailException.ACCOUNT_INCOMING_CONNECTION_FAILED, me); } } public Transport getTransport() throws MailException { Transport transport = null; try { Session session = getSession(); if (_outgoingSecure) { transport = session.getTransport("smtps"); } else { transport = session.getTransport("smtp"); } transport.connect( _outgoingHostName, _outgoingPort, _login, _password); return transport; } catch (MessagingException me) { throw new MailException( MailException.ACCOUNT_OUTGOING_CONNECTION_FAILED, me); } } public void testConnection() throws MailException { MailException mailException = null; boolean failedIncomingConnection = false; try { testIncomingConnection(); } catch (MailException me) { mailException = me; failedIncomingConnection = true; } boolean failedOutgoingConnection = false; try { testOutgoingConnection(); } catch (MailException me) { mailException = me; failedOutgoingConnection = true; } if (failedIncomingConnection && failedOutgoingConnection) { throw new MailException( MailException.ACCOUNT_CONNECTIONS_FAILED, mailException); } else if (failedIncomingConnection) { throw new MailException( MailException.ACCOUNT_INCOMING_CONNECTION_FAILED, mailException); } else if (failedOutgoingConnection) { throw new MailException( MailException.ACCOUNT_OUTGOING_CONNECTION_FAILED, mailException); } } protected boolean isJavaMailDebug() { if (_mailGroupServiceConfiguration == null) { long companyId = PortalUtil.getDefaultCompanyId(); try { _mailGroupServiceConfiguration = ConfigurationProviderUtil.getCompanyConfiguration( MailGroupServiceConfiguration.class, companyId); } catch (ConfigurationException ce) { _log.error("Unable to get mail configuration", ce); } } return _mailGroupServiceConfiguration.javamailDebug(); } protected void testIncomingConnection() throws MailException { StopWatch stopWatch = new StopWatch(); stopWatch.start(); try { Store store = getStore(false); store.close(); } catch (Exception e) { throw new MailException( MailException.ACCOUNT_INCOMING_CONNECTION_FAILED, e); } finally { if (_log.isDebugEnabled()) { stopWatch.stop(); _log.debug( "Testing incoming connection completed in " + stopWatch.getTime() + " ms"); } } } protected void testOutgoingConnection() throws MailException { StopWatch stopWatch = new StopWatch(); stopWatch.start(); try { Transport transport = getTransport(); transport.isConnected(); transport.close(); } catch (Exception e) { throw new MailException( MailException.ACCOUNT_OUTGOING_CONNECTION_FAILED, e); } finally { if (_log.isDebugEnabled()) { stopWatch.stop(); _log.debug( "Testing outgoing connection completed in " + stopWatch.getTime() + " ms"); } } } private static final String _TRANSPORT = "_TRANSPORT_"; private static final Log _log = LogFactoryUtil.getLog(IMAPConnection.class); private static final ConcurrentHashMap<String, Store> _allStores = new ConcurrentHashMap<>(); private final String _incomingHostName; private final int _incomingPort; private final boolean _incomingSecure; private final String _login; private MailGroupServiceConfiguration _mailGroupServiceConfiguration; private final String _outgoingHostName; private final int _outgoingPort; private final boolean _outgoingSecure; private final String _password; private Session _session; }