1 package com.atlassian.sal.core.upgrade;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import com.atlassian.plugin.Plugin;
9 import com.atlassian.plugin.PluginAccessor;
10 import com.atlassian.plugin.event.PluginEventListener;
11 import com.atlassian.plugin.event.PluginEventManager;
12 import com.atlassian.plugin.event.events.PluginEnabledEvent;
13 import com.atlassian.sal.api.lifecycle.LifecycleAware;
14 import com.atlassian.sal.api.message.Message;
15 import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
16 import com.atlassian.sal.api.transaction.TransactionCallback;
17 import com.atlassian.sal.api.transaction.TransactionTemplate;
18 import com.atlassian.sal.api.upgrade.PluginUpgradeManager;
19 import com.atlassian.sal.api.upgrade.PluginUpgradeTask;
20
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23 import org.springframework.beans.factory.DisposableBean;
24 import org.springframework.beans.factory.InitializingBean;
25
26
27
28
29
30
31 public class DefaultPluginUpgradeManager implements PluginUpgradeManager, LifecycleAware, InitializingBean, DisposableBean
32 {
33 private static final Logger log = LoggerFactory.getLogger(DefaultPluginUpgradeManager.class);
34
35 private volatile boolean started = false;
36
37 private final List<PluginUpgradeTask> upgradeTasks;
38 private final TransactionTemplate transactionTemplate;
39 private final PluginAccessor pluginAccessor;
40 private final PluginSettingsFactory pluginSettingsFactory;
41 private final PluginEventManager pluginEventManager;
42
43 public DefaultPluginUpgradeManager(final List<PluginUpgradeTask> upgradeTasks, final TransactionTemplate transactionTemplate,
44 final PluginAccessor pluginAccessor, final PluginSettingsFactory pluginSettingsFactory, final PluginEventManager pluginEventManager)
45 {
46 this.upgradeTasks = upgradeTasks;
47 this.transactionTemplate = transactionTemplate;
48 this.pluginAccessor = pluginAccessor;
49 this.pluginSettingsFactory = pluginSettingsFactory;
50 this.pluginEventManager = pluginEventManager;
51 }
52
53
54
55
56
57
58
59
60
61
62
63 @SuppressWarnings("unchecked")
64 @Deprecated
65 public void onBind(final PluginUpgradeTask task, final Map props)
66 {
67
68 log.debug("onbind task = [" + task.getPluginKey() + ", " + task.getBuildNumber() + "] ");
69 }
70
71 public void onStart()
72 {
73 log.debug("onStart");
74 final List<Message> messages = upgrade();
75
76
77
78 if (messages != null)
79 {
80 for (final Message msg : messages)
81 {
82 log.error("Upgrade error: " + msg);
83 }
84 }
85
86 started = true;
87 }
88
89 @PluginEventListener
90 public void onPluginEnabled(PluginEnabledEvent event)
91 {
92
93 if (started)
94 {
95
96 final List<Message> messages = upgradeInternal(event.getPlugin());
97 if (messages != null && messages.size() > 0)
98 {
99 log.error("Error(s) encountered while upgrading plugin '" + event.getPlugin().getName() + "' on enable.");
100 for (final Message msg : messages)
101 {
102 log.error("Upgrade error: " + msg);
103 }
104 }
105 }
106
107 }
108
109
110
111
112 protected Map<String, List<PluginUpgradeTask>> getUpgradeTasks()
113 {
114 final Map<String, List<PluginUpgradeTask>> pluginUpgrades = new HashMap<String, List<PluginUpgradeTask>>();
115
116
117 for (final PluginUpgradeTask upgradeTask : upgradeTasks)
118 {
119 List<PluginUpgradeTask> upgrades = pluginUpgrades.get(upgradeTask.getPluginKey());
120 if (upgrades == null)
121 {
122 upgrades = new ArrayList<PluginUpgradeTask>();
123 pluginUpgrades.put(upgradeTask.getPluginKey(), upgrades);
124 }
125 upgrades.add(upgradeTask);
126 }
127
128 return pluginUpgrades;
129 }
130
131
132 @SuppressWarnings("unchecked")
133 public List<Message> upgrade()
134 {
135 return upgradeInternal();
136 }
137
138 public List<Message> upgradeInternal()
139 {
140 log.info("Running plugin upgrade tasks...");
141
142
143 final Map<String, List<PluginUpgradeTask>> pluginUpgrades = getUpgradeTasks();
144
145
146 final ArrayList<Message> messages = new ArrayList<Message>();
147
148
149 for (final String pluginKey : pluginUpgrades.keySet())
150 {
151 final List<PluginUpgradeTask> upgrades = pluginUpgrades.get(pluginKey);
152
153 final List<Message> upgradeMessages = upgradePlugin(pluginKey, upgrades);
154 if (upgradeMessages != null)
155 {
156 messages.addAll(upgradeMessages);
157 }
158 }
159
160 return messages;
161 }
162
163 public List<Message> upgradeInternal(Plugin plugin)
164 {
165 final Map<String, List<PluginUpgradeTask>> pluginUpgrades = getUpgradeTasks();
166 final String pluginKey = plugin.getKey();
167 final List<PluginUpgradeTask> upgrades = pluginUpgrades.get(pluginKey);
168 if (upgrades == null)
169 {
170
171 return null;
172 }
173 return upgradePlugin(pluginKey, upgrades);
174 }
175
176 private List<Message> upgradePlugin(final String pluginKey, final List<PluginUpgradeTask> upgrades)
177 {
178 return transactionTemplate.execute(new TransactionCallback<List<Message>>()
179 {
180 @Override
181 public List<Message> doInTransaction()
182 {
183 final Plugin plugin = pluginAccessor.getPlugin(pluginKey);
184 if (plugin == null)
185 {
186 throw new IllegalArgumentException("Invalid plugin key: " + pluginKey);
187 }
188
189 final PluginUpgrader pluginUpgrader = new PluginUpgrader(plugin, pluginSettingsFactory.createGlobalSettings(), upgrades);
190 return pluginUpgrader.upgrade();
191 }
192 });
193 }
194
195 public void afterPropertiesSet() throws Exception
196 {
197 pluginEventManager.register(this);
198 }
199
200 public void destroy() throws Exception
201 {
202 pluginEventManager.unregister(this);
203 }
204 }