1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.atlassian.theplugin.commons.cfg;
17
18 import com.atlassian.theplugin.commons.ServerType;
19 import com.atlassian.theplugin.commons.util.MiscUtil;
20 import static com.atlassian.theplugin.commons.util.MiscUtil.buildConcurrentHashMap;
21
22 import java.util.*;
23 import java.util.concurrent.CopyOnWriteArraySet;
24
25 public class CfgManagerImpl implements CfgManager {
26 private final Map<ProjectId, ProjectConfiguration> projectConfigurations = buildConcurrentHashMap(INITIAL_CAPACITY);
27 private Collection<ServerCfg> globalServers = MiscUtil.buildArrayList();
28 private final Map<ProjectId, Collection<ConfigurationListener>> listeners = buildConcurrentHashMap(100);
29 private final Map<ProjectId, Collection<ConfigurationCredentialsListener>> credentialListeners =
30 buildConcurrentHashMap(100);
31 private BambooCfg bambooCfg;
32 private static final int INITIAL_CAPACITY = 4;
33
34 private static final ProjectListenerAction PROJECT_UNREGISTERED_LISTENER_ACTION = new ProjectListenerAction() {
35 public void run(final ConfigurationListener projectListener, final ProjectId projectId,
36 final CfgManagerImpl cfgManager) {
37 projectListener.projectUnregistered();
38 }
39 };
40
41 public CfgManagerImpl() {
42
43 update(new GlobalConfiguration());
44 }
45
46
47 public ProjectConfiguration getProjectConfiguration(final ProjectId projectId) {
48 verifyProjectId(projectId);
49 return projectConfigurations.get(projectId);
50 }
51
52 public Collection<ServerCfg> getAllServers(final ProjectId projectId) {
53 Collection<ServerCfg> tmp = new ArrayList<ServerCfg>(getProjectSpecificServers(projectId));
54 tmp.addAll(globalServers);
55 return tmp;
56 }
57
58 public Collection<CrucibleServerCfg> getAllCrucibleServers(ProjectId projectId) {
59
60 Collection<ServerCfg> tmp = getAllServers(projectId);
61 Collection<CrucibleServerCfg> res = MiscUtil.buildArrayList();
62 for (ServerCfg serverCfg : tmp) {
63 if (serverCfg.getServerType() == ServerType.CRUCIBLE_SERVER && serverCfg instanceof CrucibleServerCfg) {
64 res.add((CrucibleServerCfg) serverCfg);
65 }
66 }
67 return res;
68
69 }
70
71 public Collection<ServerCfg> getProjectSpecificServers(final ProjectId projectId) {
72 verifyProjectId(projectId);
73 ProjectConfiguration res = projectConfigurations.get(projectId);
74 if (res == null) {
75 return Collections.emptyList();
76 }
77 return MiscUtil.buildArrayList(res.getServers());
78 }
79
80 public Collection<ServerCfg> getGlobalServers() {
81 return new ArrayList<ServerCfg>(globalServers);
82 }
83
84 public Collection<ServerCfg> getAllEnabledServers(final ProjectId projectId) {
85 Collection<ServerCfg> tmp = new ArrayList<ServerCfg>();
86 for (ServerCfg serverCfg : getAllServers(projectId)) {
87 if (serverCfg.isEnabled()) {
88 tmp.add(serverCfg);
89 }
90 }
91 return tmp;
92 }
93
94
95 public BambooCfg getGlobalBambooCfg() {
96 return bambooCfg;
97 }
98
99 public void updateProjectConfiguration(final ProjectId projectId, final ProjectConfiguration projectConfiguration) {
100 verifyProjectId(projectId);
101 if (projectConfiguration == null) {
102 throw new NullPointerException("Project configuration cannot be null");
103 }
104
105
106
107 ProjectConfiguration oldConfiguration = null;
108 if (getProjectConfiguration(projectId) != null) {
109 oldConfiguration = new ProjectConfiguration(getProjectConfiguration(projectId));
110 }
111
112
113 projectConfigurations.put(projectId, projectConfiguration);
114
115 notifyListeners(projectId, projectConfiguration, oldConfiguration);
116
117
118 }
119
120 private void notifyListeners(ProjectId projectId,
121 ProjectConfiguration newConfiguration,
122 ProjectConfiguration oldConfiguration) {
123
124 ProjectListenerAction[] actions = {
125 new UpdateConfigurationListenerAction(newConfiguration),
126 new ConfigurationTypeChangedAction(newConfiguration, oldConfiguration),
127 new ServerChangedAction(newConfiguration, oldConfiguration),
128 new ServerAddedAction(newConfiguration, oldConfiguration),
129 new ServerRemovedAction(newConfiguration, oldConfiguration),
130 new ServerEnabledDisabledAction(newConfiguration, oldConfiguration)
131 };
132
133 for (ProjectListenerAction action : actions) {
134 notifyListeners(projectId, action);
135 }
136 }
137
138 private void notifyListeners(final ProjectId projectId, ProjectListenerAction listenerAction) {
139 Collection<ConfigurationListener> projectListeners = listeners.get(projectId);
140 if (projectListeners != null) {
141 for (ConfigurationListener projectListener : projectListeners) {
142 listenerAction.run(projectListener, projectId, this);
143
144 }
145 }
146 }
147
148 public void addProjectConfigurationListener(final ProjectId projectId, final ConfigurationListener configurationListener) {
149 if (configurationListener == null) {
150 throw new IllegalArgumentException(ProjectId.class.getSimpleName() + " cannot be null");
151 }
152 verifyProjectId(projectId);
153
154 Collection<ConfigurationListener> tmp = listeners.get(projectId);
155 if (tmp == null) {
156 tmp = new CopyOnWriteArraySet<ConfigurationListener>();
157 listeners.put(projectId, tmp);
158 }
159 tmp.add(configurationListener);
160 }
161
162 public boolean removeProjectConfigurationListener(final ProjectId projectId,
163 final ConfigurationListener configurationListener) {
164 if (configurationListener == null) {
165 throw new IllegalArgumentException(ProjectId.class.getSimpleName() + " cannot be null");
166 }
167 verifyProjectId(projectId);
168 Collection<ConfigurationListener> tmp = listeners.get(projectId);
169 return tmp.remove(configurationListener);
170 }
171
172 public void updateGlobalConfiguration(final GlobalConfiguration globalConfiguration) {
173 if (globalConfiguration == null) {
174 throw new NullPointerException("Global configuration cannot be null");
175 }
176
177 globalServers = MiscUtil.buildArrayList(globalConfiguration.getGlobalServers());
178 }
179
180 public void addProjectSpecificServer(final ProjectId projectId, final ServerCfg serverCfg) {
181 verifyProjectId(projectId);
182 if (serverCfg == null) {
183 throw new IllegalArgumentException(ServerCfg.class.getSimpleName() + " cannot be null");
184 }
185
186 ProjectConfiguration projectCfg = getProjectConfiguration(projectId);
187
188 if (projectCfg == null) {
189 projectCfg = new ProjectConfiguration();
190 projectConfigurations.put(projectId, projectCfg);
191 }
192 if (!projectCfg.getServers().contains(serverCfg)) {
193 projectCfg.getServers().add(serverCfg);
194 }
195
196 }
197
198 public void addGlobalServer(final ServerCfg serverCfg) {
199 globalServers.add(serverCfg);
200 }
201
202 public ProjectConfiguration removeProject(final ProjectId projectId) {
203 final ProjectConfiguration res = projectConfigurations.remove(projectId);
204 if (res != null) {
205 notifyListeners(projectId, PROJECT_UNREGISTERED_LISTENER_ACTION);
206 }
207 return res;
208 }
209
210
211 public ServerCfg removeGlobalServer(final ServerId serverId) {
212 verifyServerId(serverId);
213 return removeServer(serverId, globalServers);
214 }
215
216 private void verifyServerId(final ServerId serverId) {
217 if (serverId == null) {
218 throw new IllegalArgumentException(ServerId.class.getSimpleName() + " cannot be null");
219 }
220 }
221
222 public ServerCfg removeProjectSpecificServer(final ProjectId projectId, final ServerId serverId) {
223 verifyProjectId(projectId);
224 verifyServerId(serverId);
225
226 ProjectConfiguration projectCfg = getProjectConfiguration(projectId);
227 if (projectCfg == null) {
228 return null;
229 }
230
231 return removeServer(serverId, projectCfg.getServers());
232 }
233
234 private void verifyProjectId(final ProjectId projectId) {
235 if (projectId == null) {
236 throw new IllegalArgumentException(ProjectId.class.getSimpleName() + " cannot be null");
237 }
238 }
239
240 public boolean hasProject(ProjectId projectId) {
241 return projectConfigurations.containsKey(projectId);
242 }
243
244 public Collection<BambooServerCfg> getAllEnabledBambooServers(final ProjectId projectId) {
245 Collection<ServerCfg> tmp = getAllEnabledServers(projectId);
246 Collection<BambooServerCfg> res = MiscUtil.buildArrayList();
247 for (ServerCfg serverCfg : tmp) {
248 if (serverCfg instanceof BambooServerCfg) {
249 BambooServerCfg bambooServerCfg = (BambooServerCfg) serverCfg;
250 res.add(bambooServerCfg);
251 }
252 }
253 return res;
254 }
255
256 public ServerCfg getServer(final ProjectId projectId, final ServerId serverId) {
257 final Collection<ServerCfg> tmp = getAllServers(projectId);
258 for (ServerCfg serverCfg : tmp) {
259 if (serverCfg.getServerId().equals(serverId)) {
260 return serverCfg;
261 }
262 }
263 return null;
264 }
265
266 public Collection<CrucibleServerCfg> getAllEnabledCrucibleServers(final ProjectId projectId) {
267 Collection<ServerCfg> tmp = getAllEnabledServers(projectId);
268 Collection<CrucibleServerCfg> res = MiscUtil.buildArrayList();
269 for (ServerCfg serverCfg : tmp) {
270 if (serverCfg instanceof CrucibleServerCfg) {
271 CrucibleServerCfg bambooServerCfg = (CrucibleServerCfg) serverCfg;
272 res.add(bambooServerCfg);
273 }
274 }
275 return res;
276 }
277
278
279 public Collection<JiraServerCfg> getAllEnabledJiraServers(final ProjectId projectId) {
280 Collection<ServerCfg> tmp = getAllEnabledServers(projectId);
281 Collection<JiraServerCfg> res = MiscUtil.buildArrayList();
282 for (ServerCfg serverCfg : tmp) {
283 if (serverCfg instanceof JiraServerCfg) {
284 JiraServerCfg bambooServerCfg = (JiraServerCfg) serverCfg;
285 res.add(bambooServerCfg);
286 }
287 }
288 return res;
289 }
290
291
292 public Collection<ServerCfg> getAllEnabledServers(final ProjectId projectId, ServerType serverType) {
293 Collection<ServerCfg> tmp = getAllEnabledServers(projectId);
294 Collection<ServerCfg> res = MiscUtil.buildArrayList();
295 for (ServerCfg serverCfg : tmp) {
296 if (serverCfg.getServerType() == serverType) {
297 res.add(serverCfg);
298 }
299 }
300 return res;
301 }
302
303 private ServerCfg removeServer(final ServerId serverId, final Collection<ServerCfg> servers) {
304 Iterator<ServerCfg> it = servers.iterator();
305 while (it.hasNext()) {
306 ServerCfg serverCfg = it.next();
307 if (serverCfg.getServerId().equals(serverId)) {
308 it.remove();
309 return serverCfg;
310 }
311 }
312 return null;
313 }
314
315
316 public void update(GlobalConfiguration globalConfiguration) {
317 bambooCfg = globalConfiguration.getBambooCfg();
318 }
319
320 private interface ProjectListenerAction {
321 void run(final ConfigurationListener projectListener, final ProjectId projectId, final CfgManagerImpl cfgManager);
322 }
323
324
325 public Collection<ServerCfg> getAllUniqueServers() {
326 final Set<ServerCfg> res = new HashSet<ServerCfg>(globalServers);
327 for (ProjectConfiguration projectCfg : projectConfigurations.values()) {
328 res.addAll(projectCfg.getServers());
329 }
330 return res;
331 }
332
333
334 private static class UpdateConfigurationListenerAction implements ProjectListenerAction {
335
336 private final ProjectConfiguration projectConfiguration;
337
338 public UpdateConfigurationListenerAction(final ProjectConfiguration projectConfiguration) {
339 this.projectConfiguration = projectConfiguration;
340 }
341
342 public void run(final ConfigurationListener projectListener, final ProjectId projectId,
343 final CfgManagerImpl cfgManager) {
344 projectListener.configurationUpdated(projectConfiguration);
345 }
346 }
347
348 private class ServerChangedAction implements ProjectListenerAction {
349 protected final ProjectConfiguration newConfiguration;
350 protected ProjectConfiguration oldConfiguration;
351
352 public ServerChangedAction(ProjectConfiguration newConfiguration, ProjectConfiguration oldConfiguration) {
353 this.newConfiguration = newConfiguration;
354 this.oldConfiguration = oldConfiguration;
355 }
356
357 public void run(ConfigurationListener projectListener, ProjectId projectId, CfgManagerImpl cfgManager) {
358 if (oldConfiguration == null || newConfiguration == null) {
359 return;
360 }
361
362 for (ServerCfg oldServer : oldConfiguration.getServers()) {
363 ServerCfg newServer = newConfiguration.getServerCfg(oldServer.getServerId());
364
365
366 if (newServer != null && !oldServer.equals(newServer)) {
367 projectListener.serverDataChanged(oldServer.getServerId());
368
369
370 if (checkCredentialsChanged(oldServer, newServer)
371 || checkUrlChanged(oldServer, newConfiguration.getServerCfg(oldServer.getServerId()))) {
372 projectListener.serverConnectionDataChanged(oldServer.getServerId());
373 }
374
375
376 if (!oldServer.getName().equals(newServer.getName())) {
377 projectListener.serverNameChanged(oldServer.getServerId());
378 }
379
380 }
381 }
382 }
383
384 protected boolean checkCredentialsChanged(final ServerCfg oldServer, final ServerCfg newServer) {
385 if (newServer == null) {
386 return false;
387 }
388
389 if (!oldServer.getUsername().equals(newServer.getUsername())
390 || !oldServer.getPassword().equals(newServer.getPassword())) {
391 return true;
392 }
393
394 return false;
395 }
396
397 private boolean checkUrlChanged(final ServerCfg oldServer, final ServerCfg newServer) {
398 if (newServer == null) {
399 return false;
400 }
401 return !oldServer.getUrl().equals(newServer.getUrl());
402 }
403 }
404
405 private class ServerAddedAction implements ProjectListenerAction {
406 private final ProjectConfiguration newConfiguration;
407 private final ProjectConfiguration oldConfiguration;
408
409 public ServerAddedAction(ProjectConfiguration newConfiguration, ProjectConfiguration oldConfiguration) {
410 this.newConfiguration = newConfiguration;
411 this.oldConfiguration = oldConfiguration;
412 }
413
414 public void run(ConfigurationListener projectListener, ProjectId projectId, CfgManagerImpl cfgManager) {
415 if (oldConfiguration == null || newConfiguration == null) {
416 return;
417 }
418
419 for (ServerCfg newServer : newConfiguration.getServers()) {
420 if (oldConfiguration.getServerCfg(newServer.getServerId()) == null) {
421 projectListener.serverAdded(newServer);
422 }
423 }
424 }
425 }
426
427 private class ServerRemovedAction implements ProjectListenerAction {
428 private final ProjectConfiguration newConfiguration;
429 private final ProjectConfiguration oldConfiguration;
430
431 public ServerRemovedAction(ProjectConfiguration newConfiguration, ProjectConfiguration oldConfiguration) {
432 this.newConfiguration = newConfiguration;
433 this.oldConfiguration = oldConfiguration;
434 }
435
436 public void run(ConfigurationListener projectListener, ProjectId projectId, CfgManagerImpl cfgManager) {
437 if (oldConfiguration == null || newConfiguration == null) {
438 return;
439 }
440
441 for (ServerCfg oldServer : oldConfiguration.getServers()) {
442 if (newConfiguration.getServerCfg(oldServer.getServerId()) == null) {
443 projectListener.serverRemoved(oldServer);
444 }
445 }
446 }
447 }
448
449 private class ServerEnabledDisabledAction implements ProjectListenerAction {
450
451 private final ProjectConfiguration newConfiguration;
452 private final ProjectConfiguration oldConfiguration;
453
454 public ServerEnabledDisabledAction(ProjectConfiguration newConfiguration, ProjectConfiguration oldConfiguration) {
455 this.newConfiguration = newConfiguration;
456 this.oldConfiguration = oldConfiguration;
457 }
458
459 public void run(ConfigurationListener projectListener, ProjectId projectId, CfgManagerImpl cfgManager) {
460 if (oldConfiguration == null || newConfiguration == null) {
461 return;
462 }
463
464 for (ServerCfg oldServer : oldConfiguration.getServers()) {
465 ServerCfg newServer = newConfiguration.getServerCfg(oldServer.getServerId());
466 if (newServer != null) {
467 if (!oldServer.isEnabled() && newServer.isEnabled()) {
468 projectListener.serverEnabled(oldServer.getServerId());
469 } else if (oldServer.isEnabled() && !newServer.isEnabled()) {
470 projectListener.serverDisabled(oldServer.getServerId());
471 }
472 }
473 }
474 }
475
476 }
477
478 private class ConfigurationTypeChangedAction implements ProjectListenerAction {
479 private final ProjectConfiguration newConfiguration;
480 private final ProjectConfiguration oldConfiguration;
481
482 public ConfigurationTypeChangedAction(
483 ProjectConfiguration newConfiguration, ProjectConfiguration oldConfiguration) {
484 this.newConfiguration = newConfiguration;
485 this.oldConfiguration = oldConfiguration;
486 }
487
488 public void run(ConfigurationListener projectListener, ProjectId projectId, CfgManagerImpl cfgManager) {
489 if (oldConfiguration == null || newConfiguration == null) {
490 return;
491 }
492
493
494
495
496
497
498
499 Collection<JiraServerCfg> newJiraServers = newConfiguration.getAllJIRAServers();
500 Collection<JiraServerCfg> oldJiraServers = oldConfiguration.getAllJIRAServers();
501 if (!newJiraServers.containsAll(oldJiraServers) || !oldJiraServers.containsAll(newJiraServers)) {
502 projectListener.jiraServersChanged(newConfiguration);
503 }
504
505
506 Collection<BambooServerCfg> newBambooServers = newConfiguration.getAllBambooServers();
507 Collection<BambooServerCfg> oldBambooServers = oldConfiguration.getAllBambooServers();
508 if (!newBambooServers.containsAll(oldBambooServers) || !oldBambooServers.containsAll(newBambooServers)) {
509 projectListener.bambooServersChanged(newConfiguration);
510 }
511
512
513 Collection<CrucibleServerCfg> newCrucibleServers = newConfiguration.getAllCrucibleServers();
514 Collection<CrucibleServerCfg> oldCrucibleServers = oldConfiguration.getAllCrucibleServers();
515 if (!newCrucibleServers.containsAll(oldCrucibleServers) || !oldCrucibleServers.containsAll(newCrucibleServers)) {
516 projectListener.crucibleServersChanged(newConfiguration);
517 }
518
519
520 Collection<FishEyeServerCfg> newFisheyeServers = newConfiguration.getAllFisheyeServers();
521 Collection<FishEyeServerCfg> oldFisheyeServers = oldConfiguration.getAllFisheyeServers();
522 if (!newFisheyeServers.containsAll(oldFisheyeServers) || !oldFisheyeServers.containsAll(newFisheyeServers)) {
523 projectListener.fisheyeServersChanged(newConfiguration);
524 }
525 }
526 }
527 }