1   package com.atlassian.mail.server.managers;
2   
3   import com.atlassian.core.util.ClassLoaderUtils;
4   import com.atlassian.mail.MailException;
5   import com.atlassian.mail.config.ConfigLoader;
6   import com.atlassian.mail.server.MailServer;
7   import com.atlassian.mail.server.PopMailServer;
8   import com.atlassian.mail.server.SMTPMailServer;
9   import com.atlassian.mail.server.impl.PopMailServerImpl;
10  import com.atlassian.mail.server.impl.SMTPMailServerImpl;
11  import org.apache.commons.digester.Digester;
12  import org.apache.commons.digester.ExtendedBaseRules;
13  import org.apache.log4j.Logger;
14  
15  import javax.annotation.Nullable;
16  import java.io.InputStream;
17  import java.util.ArrayList;
18  import java.util.HashMap;
19  import java.util.List;
20  import java.util.Map;
21  
22  public class XMLMailServerManager extends AbstractMailServerManager {
23  	private static final Logger log = Logger.getLogger(XMLMailServerManager.class);
24  
25  	// Map of server id -> server
26  	Map<Long, MailServer> serverIds;
27  
28  	private static String DEFAULT_CONFIG_FILE = "mail-servers.xml";
29  
30  	String configFile;
31  
32  	public void init(Map params) {
33  		configFile = DEFAULT_CONFIG_FILE;
34  		serverIds = new HashMap<Long, MailServer>();
35  
36  		if (params.containsKey("config-file")) {
37  			configFile = (String) params.get("config-file");
38  		}
39  
40  		configure();
41  	}
42  
43  	private void configure() {
44  		// configure from config file
45  		try {
46              Digester digester = newDigester();
47              digester.push(this);
48  			digester.setRules(new ExtendedBaseRules());
49  
50  			// load pop servers
51  			digester.addObjectCreate("mail-servers/pop-server", getPopMailServerClass());
52  			digester.addSetProperties("mail-servers/pop-server");
53  			digester.addBeanPropertySetter("mail-servers/pop-server/?");
54  			digester.addSetRoot("mail-servers/pop-server", "create");
55  
56  			// load smtp servers
57  			digester.addObjectCreate("mail-servers/smtp-server", getSMTPMailServerClass());
58  			digester.addSetProperties("mail-servers/smtp-server");
59  			digester.addBeanPropertySetter("mail-servers/smtp-server/?");
60  			digester.addBeanPropertySetter("mail-servers/smtp-server/jndi-location", "jndiLocation");
61  			digester.addSetRoot("mail-servers/smtp-server", "create");
62  
63  			InputStream is = getConfigurationInputStream(configFile);
64  			digester.parse(is);
65  
66  
67  		} catch (Exception e) {
68  			log.fatal(e, e);
69  			throw new RuntimeException("Error in mail config: " + e.getMessage(), e);
70  		}
71  	}
72  
73      protected Digester newDigester()
74      {
75          return new Digester();
76      }
77  
78      protected InputStream getConfigurationInputStream(String resource) {
79  		return ClassLoaderUtils.getResourceAsStream(resource, ConfigLoader.class);
80  	}
81  
82  	public String getConfigFile() {
83  		return configFile;
84  	}
85  
86  	@Nullable
87  	public MailServer getMailServer(Long id) {
88  		return serverIds.get(id);
89  	}
90  
91  	@Nullable
92  	public MailServer getMailServer(String name) throws MailException {
93  		if (name == null) {
94  			throw new MailException("name is null");
95  		}
96  
97  		for (MailServer server : serverIds.values()) {
98  			if (name.equals(server.getName())) {
99  				return server;
100 			}
101 		}
102 
103 		return null;
104 	}
105 
106 	public synchronized Long create(MailServer mailServer) throws MailException {
107 		Long id = new Long((serverIds.size() + 1));
108 
109 		// check if this id already exists. If it does, increment until a vacant one is found
110 		// this will not scale! (we are assuming there won't be that many mail servers)
111 		while (serverIds.containsKey(id)) {
112 			id = new Long(id.longValue() + 1);
113 		}
114 
115 		mailServer.setId(id);
116 		serverIds.put(id, mailServer);
117 		return id;
118 	}
119 
120 	public void update(MailServer mailServer) throws MailException {
121 		serverIds.put(mailServer.getId(), mailServer);
122 	}
123 
124 	public void delete(Long mailServerId) throws MailException {
125 		if (mailServerId == null) {
126 			throw new MailException("mailServerId is null");
127 		}
128 		if (!serverIds.containsKey(mailServerId)) {
129 			throw new MailException("A mail server with the specified mailServerId does not exist");
130 		}
131 
132 		serverIds.remove(mailServerId);
133 	}
134 
135 	public List<String> getServerNames() throws MailException {
136 		List<String> result = new ArrayList<String>();
137 
138 		for (MailServer server : serverIds.values()) {
139 			result.add(server.getName());
140 		}
141 
142 		return result;
143 	}
144 
145     public List<SMTPMailServer> getSmtpMailServers() {
146         final List<SMTPMailServer> result = new ArrayList<SMTPMailServer>();
147 
148         for (MailServer server : serverIds.values()) {
149             if (server instanceof SMTPMailServer) {
150                 result.add((SMTPMailServer) server);
151             }
152         }
153 
154         return result;
155     }
156 
157     public List<PopMailServer> getPopMailServers() {
158 		final List<PopMailServer> result = new ArrayList<PopMailServer>();
159 
160 		for (MailServer server : serverIds.values()) {
161 			if (server instanceof PopMailServer) {
162 				result.add((PopMailServer) server);
163 			}
164 		}
165 
166 		return result;
167 	}
168 
169 	@Nullable
170 	public SMTPMailServer getDefaultSMTPMailServer() {
171 		List<SMTPMailServer> smtpServers = getSmtpMailServers();
172 
173 		if (smtpServers.size() > 0) {
174 			return smtpServers.get(0);
175 		}
176 
177 		return null;
178 	}
179 
180 	@Nullable
181 	public PopMailServer getDefaultPopMailServer() {
182 		List<PopMailServer> popServers = getPopMailServers();
183 
184 		if (popServers.size() > 0) {
185 			return popServers.get(0);
186 		}
187 
188 		return null;
189 	}
190 
191 	protected Class getSMTPMailServerClass() {
192 		return SMTPMailServerImpl.class;
193 	}
194 
195 	protected Class getPopMailServerClass() {
196 		return PopMailServerImpl.class;
197 	}
198 }