1   /*
2    * Created by IntelliJ IDEA.
3    * User: owen
4    * Date: Nov 22, 2002
5    * Time: 3:33:27 PM
6    * CVS Revision: $Revision: 1.6 $
7    * Last CVS Commit: $Date: 2006/09/29 02:48:01 $
8    * Author of last CVS Commit: $Author: cowen $
9    * To change this template use Options | File Templates.
10   */
11  package com.atlassian.mail.server;
12  
13  import com.atlassian.mail.MailProtocol;
14  import org.apache.commons.lang.StringUtils;
15  import org.apache.commons.lang.builder.EqualsBuilder;
16  import org.apache.commons.lang.builder.HashCodeBuilder;
17  import org.apache.commons.lang.builder.ToStringBuilder;
18  import org.apache.log4j.Category;
19  
20  import javax.mail.Authenticator;
21  import java.io.PrintStream;
22  import java.io.Serializable;
23  import java.io.ObjectInputStream;
24  import java.io.IOException;
25  import java.util.Properties;
26  
27  public abstract class AbstractMailServer implements MailServer, Serializable
28  {
29      protected transient Category LOG = Category.getInstance(this.getClass());
30      private Long id;
31      private String name;
32      private String description;
33      private String hostname;
34      private String username = null;
35      private String password = null;
36      private MailProtocol mailProtocol = null;
37      private String port = null;
38      private long timeout;
39      private boolean debug;
40      private boolean tlsRequired;
41      private transient PrintStream debugStream;
42      private Properties props = new Properties();
43      protected boolean isAuthenticating;
44  
45      public AbstractMailServer()
46      {
47      }
48  
49      public AbstractMailServer(Long id, String name, String description, MailProtocol protocol, String hostName, String port, String username, String password, long timeout)
50      {
51          setId(id);
52          setName(name);
53          setDescription(description);
54          setHostname(hostName);
55          setUsername(username);
56          setPassword(password);
57          setMailProtocol(protocol);
58          setPort(port);
59          setTimeout(timeout);
60          //MAIL-60: Need to ensure that system properties get set for mail servers.
61          this.props = loadSystemProperties(props);
62      }
63  
64      private void setInitialProperties()
65      {
66          if (getMailProtocol() != null)
67          {
68              final String protocol = getMailProtocol().getProtocol();
69              props.put("mail."+protocol+".host",""+getHostname());
70              props.put("mail."+protocol+".port", ""+getPort());
71              props.put("mail."+protocol+".timeout",""+getTimeout());
72              props.put("mail.transport.protocol",""+ protocol);
73              if (isTlsRequired())
74              {
75                  props.put("mail."+protocol+".starttls.enable","true");
76              }
77              if (StringUtils.isNotBlank(getUsername()))
78              {
79                  props.put("mail."+protocol+".auth", "true");
80                  isAuthenticating = true;
81              }
82          }
83          props.put("mail.debug", ""+getDebug());
84          if (Boolean.getBoolean("mail.debug"))
85          {
86              props.put("mail.debug", "true");
87          }
88      }
89  
90      protected abstract Authenticator getAuthenticator();
91  
92      public Long getId()
93      {
94          return id;
95      }
96  
97      public void setId(Long id)
98      {
99          this.id = id;
100         propertyChanged();
101     }
102 
103     public String getName()
104     {
105         return name;
106     }
107 
108     public void setName(String name)
109     {
110         this.name = name;
111         propertyChanged();
112     }
113 
114     public String getDescription()
115     {
116         return description;
117     }
118 
119     public void setDescription(String description)
120     {
121         this.description = description;
122         propertyChanged();
123     }
124 
125     public String getHostname()
126     {
127         return hostname;
128     }
129 
130     public void setHostname(String serverName)
131     {
132         this.hostname = serverName;
133         propertyChanged();
134     }
135 
136     public String getUsername()
137     {
138         return username;
139     }
140 
141     public void setUsername(String username)
142     {
143         if (StringUtils.isNotBlank(username))
144             this.username = username;
145         else
146             this.username = null;
147         propertyChanged();
148     }
149 
150     public String getPassword()
151     {
152         return password;
153     }
154 
155     public void setPassword(String password)
156     {
157         if (StringUtils.isNotBlank(password))
158             this.password = password;
159         else
160             this.password = null;
161         propertyChanged();
162     }
163 
164     public MailProtocol getMailProtocol()
165      {
166          return mailProtocol;
167      }
168 
169      public void setMailProtocol(final MailProtocol protocol)
170      {
171          this.mailProtocol = protocol;
172          propertyChanged();
173      }
174 
175      public String getPort()
176      {
177          return port;
178      }
179 
180      public void setPort(final String port)
181      {
182          this.port = port;
183          propertyChanged();
184      }
185 
186     public long getTimeout()
187     {
188         return timeout;
189     }
190 
191     public void setTimeout(long timeout)
192     {
193         this.timeout = timeout;
194         propertyChanged();
195     }
196 
197     public boolean isTlsRequired()
198     {
199         return tlsRequired;
200     }
201 
202     public void setTlsRequired(final boolean tlsRequired)
203     {
204         this.tlsRequired = tlsRequired;
205         propertyChanged();
206     }
207 
208     public Properties getProperties()
209     {
210         return props;
211     }
212 
213     public void setProperties(Properties props)
214     {
215         this.props = props;
216         propertyChanged();
217     }
218 
219     public void setDebug(boolean debug) {
220         this.debug = debug;
221         propertyChanged();
222     }
223 
224     public void setDebugStream(PrintStream debugStream) {
225         this.debugStream = debugStream;
226         propertyChanged();
227     }
228 
229 
230     public boolean getDebug() {
231         return this.debug;
232     }
233 
234     public PrintStream getDebugStream() {
235         return this.debugStream;
236     }
237 
238     ///CLOVER:OFF
239     public boolean equals(Object o)
240     {
241         if (this == o) return true;
242         if (!(o instanceof AbstractMailServer)) return false;
243         final AbstractMailServer abstractMailServer = (AbstractMailServer) o;
244         return new EqualsBuilder()
245                 .append(id, abstractMailServer.id)
246                 .append(name, abstractMailServer.name)
247                 .append(description, abstractMailServer.description)
248                 .append(hostname, abstractMailServer.hostname)
249                 .append(username, abstractMailServer.username)
250                 .append(password, abstractMailServer.password)
251                 .append(mailProtocol, abstractMailServer.mailProtocol)
252                 .append(port, abstractMailServer.port)
253                 .isEquals();
254     }
255 
256     public int hashCode() {
257         return new HashCodeBuilder()
258                 .append(id)
259                 .append(name)
260                 .append(description)
261                 .append(hostname)
262                 .append(username)
263                 .append(password)
264                 .append(mailProtocol)
265                 .append(port)
266                 .toHashCode();
267     }
268 
269     public String toString()
270     {
271         return new ToStringBuilder(this).append("id", id).append("name", name).append("description", description).append("server name", hostname).append("username", username).append("password", password).toString();
272     }
273 
274     /**
275      * Call this method whenever a property of the server changes.
276      * Subclasses should override it to clear any cached information.
277      */
278     protected void propertyChanged()
279     {
280         setInitialProperties();
281     }
282 
283     private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
284     {
285         ois.defaultReadObject();
286         LOG = Category.getInstance(this.getClass());
287     }
288 
289     /**
290      * This allows users of atlassian mail to add command line properties to modify session defaults
291      * See JRA-11452
292      *
293      * The hierarchy now is - default properties, then from the command line, then properties added via setProperties
294      *
295      * @param p the default properties for the current mail session
296      * @return  the properties with the system properties loaded
297      */
298     protected synchronized Properties loadSystemProperties(Properties p)
299     {
300         Properties props = new Properties();
301         props.putAll(p);
302         props.putAll(System.getProperties());
303         if (this.props != null)
304         {
305             props.putAll(this.props);
306         }
307         return props;
308     }
309 
310     
311 }