/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * 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.alibaba.citrus.service.mail.session; import static com.alibaba.citrus.service.mail.MailConstant.*; import static com.alibaba.citrus.util.Assert.*; import static com.alibaba.citrus.util.ObjectUtil.*; import static com.alibaba.citrus.util.StringUtil.*; import java.util.Map; import java.util.Properties; import javax.mail.Session; import com.alibaba.citrus.service.mail.MailException; import com.alibaba.citrus.service.mail.MailService; import com.alibaba.citrus.util.ToStringBuilder; import com.alibaba.citrus.util.ToStringBuilder.MapBuilder; /** * 这个类包装了<code>java.mail.Session</code>,以更友好的方式来支持mail transport和store。 * <p> * 注意,<code>java.mail.Session</code>是在多次调用和多个线程中共享的,而<code>MailSession</code> * 被设计成每次调用都创建新的。 * </p> * * @author Michael Zhou */ public abstract class MailSession { private final Properties props = new Properties(); private MailService mailService; private Session session; private String host; private int port; private String user; private String password; private boolean debug; private boolean defaultSession; /** 创建一个mail session。 */ public MailSession() { } /** 复制一个mail session。 */ public MailSession(MailSession session, Properties overrideProps) { this.mailService = session.mailService; this.session = session.getSession(); // 注意,此方法是synchronized。 this.host = session.host; this.port = session.port; this.user = session.user; this.password = session.password; this.debug = session.debug; this.defaultSession = false; // default value not copied this.props.putAll(session.props); if (overrideProps != null) { for (Object element : overrideProps.keySet()) { String key = (String) element; String value = overrideProps.getProperty(key); // 注意,执行此方法时,如果key/value和原值不同,session将被清空。 setProperty(key, value, null); } } } /** 取得创建该session的mail service。 */ public MailService getMailService() { return mailService; } /** 设置mail service。 */ public void setMailService(MailService mailService) { this.mailService = mailService; } /** 取得mail server的服务器名或IP地址。 */ public String getHost() { return host; } /** 设置mail server的服务器名或IP地址。 */ public void setHost(String host) { this.host = trimToNull(host); } /** 取得mail server的服务器端口。 */ public int getPort() { return port > 0 ? port : -1; } /** 设置mail server的服务器端口。 */ public void setPort(int port) { this.port = port; } /** 判断是否需要验证。 */ public boolean useAuth() { return user != null; } /** 取得mail server的验证用户。 */ public String getUser() { return user; } /** 设置mail server的验证用户。 */ public void setUser(String user) { this.user = trimToNull(user); } /** 取得mail server的验证密码。 */ public String getPassword() { return password; } /** 设置mail server的验证密码。 */ public void setPassword(String password) { this.password = trimToNull(password); } /** 是否是debug模式。在此模式下,javamail会打印出具体的信息。 */ public boolean isDebug() { return debug; } /** 设置debug模式。在此模式下,javamail会打印出具体的信息。 */ public void setDebug(boolean debug) { this.debug = debug; } /** * 是否为默认的transport或store。 * <p> * 在一个<code>MailService</code>中只能有一个默认的transport和一个默认的store。 * </p> */ public boolean isDefault() { return defaultSession; } /** * 设置为默认的transport或store。 * <p> * 在一个<code>MailService</code>中只能有一个默认的transport和一个默认的store。 * </p> */ public void setDefault(boolean defaultSession) { this.defaultSession = defaultSession; } /** 批量设置属性。 */ public void setProperties(Map<String, String> props) { if (props != null) { this.props.clear(); for (Map.Entry<String, String> entry : props.entrySet()) { String key = assertNotNull(trimToNull(entry.getKey()), "propertyName"); String value = trimToNull(entry.getValue()); setProperty(key, value); } } } /** 设置session的属性,如果值被改变了,则清除session。 */ public void setProperty(String key, String value) { setProperty(key, value, null); } /** 设置session的属性,如果值被改变了,则清除session。 */ protected final void setProperty(String key, String value, String defaultValue) { String currentValue = props.getProperty(key, defaultValue); if (!isEquals(currentValue, value)) { props.setProperty(key, value); session = null; } } /** 取得session properties。 */ protected Properties getSessionProperties() { setProperty(MAIL_DEBUG, String.valueOf(isDebug()), "false"); return props; } /** * 取得javamail session。 * <p> * 此方法是线程安全的,尤其是在复制session的时候。 * </p> */ protected synchronized Session getSession() { // 注意,在执行此方法时,session有可能被清空。 Properties props = getSessionProperties(); if (session == null) { session = Session.getInstance(props); } return session; } /** 判断是否已经连接上。 */ protected abstract boolean isConnected(); /** 连接mail服务器。 */ protected abstract void connect() throws MailException; /** 关闭mail服务器的连接。 */ protected abstract void close() throws MailException; @Override public final String toString() { MapBuilder mb = new MapBuilder().setSortKeys(true).setPrintCount(true); mb.append("host", getHost()); mb.append("port", getPort()); mb.append("user", getUser()); mb.append("password", getPassword()); mb.append("debug", isDebug()); mb.append("default", isDefault()); mb.append("otherProperties", props); toString(mb); return new ToStringBuilder().append(getClass().getSimpleName()).append(mb).toString(); } protected abstract void toString(MapBuilder mb); }