1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.atlassian.theplugin.idea.autoupdate;
18
19 import com.atlassian.theplugin.commons.configuration.GeneralConfigurationBean;
20 import com.atlassian.theplugin.util.InfoServer;
21 import com.atlassian.theplugin.util.PluginUtil;
22 import com.intellij.ide.plugins.IdeaPluginDescriptor;
23 import com.intellij.ide.plugins.PluginManager;
24 import com.intellij.ide.startup.StartupActionScriptManager;
25 import com.intellij.openapi.application.ApplicationManager;
26 import com.intellij.openapi.application.PathManager;
27 import com.intellij.openapi.extensions.PluginId;
28 import com.intellij.openapi.ui.DialogWrapper;
29 import com.intellij.openapi.ui.Messages;
30 import com.intellij.openapi.util.io.FileUtil;
31 import com.intellij.openapi.util.io.StreamUtil;
32 import com.intellij.util.io.ZipUtil;
33
34 import java.io.*;
35 import java.net.HttpURLConnection;
36 import java.net.URL;
37 import java.net.URLConnection;
38 import java.net.URLEncoder;
39
40
41
42
43
44
45
46
47
48 public class PluginDownloader {
49
50
51 public static final String PLUGIN_ID_TOKEN = "PLUGIN_ID";
52 public static final String VERSION_TOKEN = "BUILD";
53
54 private static String pluginName = PluginUtil.getInstance().getName();
55
56 private static final int TIMEOUT = 15000;
57 private static final int EXTENTION_LENGHT = 3;
58 private InfoServer.VersionInfo newVersion;
59 private GeneralConfigurationBean updateConfiguration;
60
61 public void setTimeout(int timeout) {
62 this.timeout = timeout;
63 }
64
65 public void setReadTimeout(int readTimeout) {
66 this.readTimeout = readTimeout;
67 }
68
69 private int timeout = TIMEOUT;
70 private int readTimeout = TIMEOUT;
71
72 public PluginDownloader(InfoServer.VersionInfo newVersion, GeneralConfigurationBean updateConfiguration) {
73 this.newVersion = newVersion;
74 this.updateConfiguration = updateConfiguration;
75 }
76
77 public void run() {
78 try {
79 File localArchiveFile = downloadPluginFromServer(this.newVersion.getDownloadUrl());
80
81
82
83
84
85
86 IdeaPluginDescriptor pluginDescr = PluginManager.getPlugin(PluginId.getId(PluginUtil.getInstance().getPluginId()));
87
88
89
90 if (pluginDescr == null) {
91 pluginDescr = PluginManager.getPlugin(PluginId.getId(PluginUtil.getInstance().getName()));
92 }
93 addActions(pluginDescr, localArchiveFile);
94
95
96 promptShutdownAndShutdown();
97
98 } catch (IOException e) {
99 PluginUtil.getLogger().info("Error registering action in IDEA", e);
100 }
101 }
102
103 private void promptShutdownAndShutdown() {
104 ApplicationManager.getApplication().invokeLater(new Runnable() {
105 public void run() {
106 String title = "IDEA shutdown";
107 String message =
108 "Plugin has been installed successfully. Do you want to restart IDEA to activate the plugin?";
109
110 int answer = Messages.showYesNoDialog(
111 message, title, Messages.getQuestionIcon());
112
113
114
115
116
117
118
119 if (answer == DialogWrapper.OK_EXIT_CODE) {
120
121 ApplicationManager.getApplication().exit();
122 }
123 }
124 });
125 }
126
127
128 private File downloadPluginFromServer(String version) throws IOException {
129 File pluginArchiveFile = FileUtil.createTempFile("temp_" + pluginName + "_", "tmp");
130
131
132 String pluginUrl = null;
133 pluginUrl = newVersion.getDownloadUrl()
134 .replaceAll(PLUGIN_ID_TOKEN, URLEncoder.encode(pluginName, "UTF-8"))
135 .replaceAll(VERSION_TOKEN, URLEncoder.encode(version, "UTF-8"));
136 if (!pluginUrl.contains("?")) {
137 pluginUrl += "?";
138 }
139 pluginUrl += "uid=" + URLEncoder.encode(Long.toString(updateConfiguration.getUid()), "UTF-8");
140
141 PluginUtil.getLogger().info("Downloading plugin archive from: " + pluginUrl);
142
143
144 URL url = new URL(pluginUrl);
145 URLConnection connection = url.openConnection();
146 connection.setConnectTimeout(getTimeout());
147 connection.setReadTimeout(getReadTimeout());
148 connection.connect();
149
150 InputStream inputStream = null;
151 OutputStream outputStream = null;
152 try {
153 inputStream = connection.getInputStream();
154 outputStream = new FileOutputStream(pluginArchiveFile);
155 StreamUtil.copyStreamContent(inputStream, outputStream);
156 } finally {
157 if (inputStream != null) {
158 try {
159 inputStream.close();
160 } catch (IOException ioe) {
161
162 }
163 }
164
165 if (outputStream != null) {
166 try {
167 outputStream.close();
168 } catch (IOException ioe) {
169
170 }
171 }
172
173 if (connection instanceof HttpURLConnection) {
174 ((HttpURLConnection) connection).disconnect();
175 }
176 }
177 String srcName = connection.getURL().toString();
178 String ext = srcName.substring(srcName.lastIndexOf("."));
179 if (ext.contains("?")) {
180 ext = ext.substring(0, ext.indexOf("?"));
181 }
182 String newName = pluginArchiveFile.getPath().substring(0, pluginArchiveFile.getPath().length()
183 - EXTENTION_LENGHT) + ext;
184 File newFile = new File(newName);
185 if (!pluginArchiveFile.renameTo(new File(newName))) {
186 pluginArchiveFile.delete();
187 throw new IOException("Renaming received file from \"" + srcName + "\" to \"" + newName + "\" failed.");
188 }
189 return newFile;
190 }
191
192 private void addActions(IdeaPluginDescriptor installedPlugin, File localArchiveFile) throws IOException {
193
194 PluginId id = installedPlugin.getPluginId();
195
196 if (PluginManager.isPluginInstalled(id)) {
197
198 File oldFile = installedPlugin.getPath();
199 StartupActionScriptManager.ActionCommand deleteOld = new StartupActionScriptManager.DeleteCommand(oldFile);
200 StartupActionScriptManager.addActionCommand(deleteOld);
201 }
202
203
204 boolean isJarFile = localArchiveFile.getName().endsWith(".jar")
205 || localArchiveFile.getName().contains(".jar?");
206
207 if (isJarFile) {
208
209 String fileName = localArchiveFile.getName();
210 File newFile = new File(PathManager.getPluginsPath() + File.separator + fileName);
211 StartupActionScriptManager.ActionCommand copyPlugin =
212 new StartupActionScriptManager.CopyCommand(localArchiveFile, newFile);
213 StartupActionScriptManager.addActionCommand(copyPlugin);
214 } else {
215
216 String unzipPath;
217 if (ZipUtil.isZipContainsFolder(localArchiveFile)) {
218 unzipPath = PathManager.getPluginsPath();
219 } else {
220 String dirName = installedPlugin.getName();
221 unzipPath = PathManager.getPluginsPath() + File.separator + dirName;
222 }
223
224 File newFile = new File(unzipPath);
225 StartupActionScriptManager.ActionCommand unzip =
226 new StartupActionScriptManager.UnzipCommand(localArchiveFile, newFile);
227 StartupActionScriptManager.addActionCommand(unzip);
228 }
229
230
231 StartupActionScriptManager.ActionCommand deleteTemp =
232 new StartupActionScriptManager.DeleteCommand(localArchiveFile);
233 StartupActionScriptManager.addActionCommand(deleteTemp);
234 }
235
236 public int getTimeout() {
237 return timeout;
238 }
239
240 public int getReadTimeout() {
241 return readTimeout;
242 }
243 }