2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.ide
.plugins
;
18 import com
.intellij
.CommonBundle
;
19 import com
.intellij
.ide
.IdeBundle
;
20 import com
.intellij
.ide
.startup
.StartupActionScriptManager
;
21 import com
.intellij
.openapi
.application
.ApplicationInfo
;
22 import com
.intellij
.openapi
.extensions
.PluginId
;
23 import com
.intellij
.openapi
.progress
.ProgressIndicator
;
24 import com
.intellij
.openapi
.progress
.ProgressManager
;
25 import com
.intellij
.openapi
.ui
.DialogWrapper
;
26 import com
.intellij
.openapi
.ui
.Messages
;
27 import com
.intellij
.openapi
.updateSettings
.impl
.PluginDownloader
;
28 import com
.intellij
.openapi
.util
.BuildNumber
;
29 import com
.intellij
.ui
.GuiUtils
;
30 import org
.jetbrains
.annotations
.NonNls
;
33 import java
.io
.IOException
;
34 import java
.net
.URLEncoder
;
35 import java
.util
.ArrayList
;
36 import java
.util
.Arrays
;
37 import java
.util
.List
;
40 * Created by IntelliJ IDEA.
44 * To change this template use Options | File Templates.
46 public class PluginInstaller
{
48 private PluginInstaller() {}
50 public static boolean prepareToInstall (List
<PluginNode
> plugins
) {
51 ProgressIndicator pi
= ProgressManager
.getInstance().getProgressIndicator();
53 final List
<PluginId
> pluginIds
= new ArrayList
<PluginId
>();
54 for (PluginNode pluginNode
: plugins
) {
55 pluginIds
.add(pluginNode
.getPluginId());
58 boolean result
= false;
60 for (final PluginNode pluginNode
: plugins
) {
61 if (pi
!= null) pi
.setText(pluginNode
.getName());
64 result
|= prepareToInstall(pluginNode
, pluginIds
);
66 catch (final IOException e
) {
67 SwingUtilities
.invokeLater(new Runnable(){
69 Messages
.showErrorDialog(pluginNode
.getName() + ": " + e
.getMessage(), CommonBundle
.message("title.error"));
77 private static boolean prepareToInstall(final PluginNode pluginNode
, final List
<PluginId
> pluginIds
) throws IOException
{
78 // check for dependent plugins at first.
79 if (pluginNode
.getDepends() != null && pluginNode
.getDepends().size() > 0) {
80 // prepare plugins list for install
82 final PluginId
[] optionalDependentPluginIds
= pluginNode
.getOptionalDependentPluginIds();
83 final List
<PluginNode
> depends
= new ArrayList
<PluginNode
> ();
84 final List
<PluginNode
> optionalDeps
= new ArrayList
<PluginNode
>();
85 for (int i
= 0; i
< pluginNode
.getDepends().size(); i
++) {
86 PluginId depPluginId
= pluginNode
.getDepends().get(i
);
88 if (PluginManager
.isPluginInstalled(depPluginId
) || PluginManager
.isModuleDependency(depPluginId
) ||
89 (pluginIds
!= null && pluginIds
.contains(depPluginId
))) {
90 // ignore installed or installing plugins
94 PluginNode depPlugin
= new PluginNode(depPluginId
);
95 depPlugin
.setSize("-1");
96 depPlugin
.setName(depPluginId
.getIdString()); //prevent from exceptions
98 if (optionalDependentPluginIds
!= null && Arrays
.binarySearch(optionalDependentPluginIds
, depPluginId
) != -1) {
99 optionalDeps
.add(depPlugin
);
101 depends
.add(depPlugin
);
105 if (depends
.size() > 0) { // has something to install prior installing the plugin
106 final boolean [] proceed
= new boolean[1];
107 final StringBuffer buf
= new StringBuffer();
108 for (PluginNode depend
: depends
) {
109 buf
.append(depend
.getName()).append(",");
112 GuiUtils
.runOrInvokeAndWait(new Runnable() {
114 proceed
[0] = Messages
.showYesNoDialog(IdeBundle
.message("plugin.manager.dependencies.detected.message", depends
.size(), buf
.substring(0, buf
.length() - 1)),
115 IdeBundle
.message("plugin.manager.dependencies.detected.title"), Messages
.getWarningIcon()) == DialogWrapper
.OK_EXIT_CODE
;
119 catch (Exception e
) {
123 if (!prepareToInstall(depends
)) {
131 if (optionalDeps
.size() > 0) {
132 final StringBuffer buf
= new StringBuffer();
133 for (PluginNode depend
: optionalDeps
) {
134 buf
.append(depend
.getName()).append(",");
136 final boolean [] proceed
= new boolean[1];
138 GuiUtils
.runOrInvokeAndWait(new Runnable() {
140 proceed
[0] = Messages
.showYesNoDialog(IdeBundle
.message("plugin.manager.optional.dependencies.detected.message", optionalDeps
.size(),
141 buf
.substring(0, buf
.length() - 1)), IdeBundle
.message("plugin.manager.dependencies.detected.title"),
142 Messages
.getWarningIcon()) == DialogWrapper
.OK_EXIT_CODE
;
146 catch (Exception e
) {
150 if (!prepareToInstall(optionalDeps
)) {
157 synchronized (PluginManager
.lock
) {
158 final BuildNumber buildNumber
= ApplicationInfo
.getInstance().getBuild();
159 final @NonNls String url
= RepositoryHelper
.DOWNLOAD_URL
+
160 URLEncoder
.encode(pluginNode
.getPluginId().getIdString(), "UTF8") +
161 "&build=" + buildNumber
.asString();
162 final PluginDownloader downloader
=
163 new PluginDownloader(pluginNode
.getPluginId().getIdString(), url
, null, null, pluginNode
.getName());
164 if (downloader
.prepareToInstall(ProgressManager
.getInstance().getProgressIndicator())) {
165 downloader
.install();
166 pluginNode
.setStatus(PluginNode
.STATUS_DOWNLOADED
);
173 * Install plugin into a temp direcotry
174 * Append 'action script' file with installing actions
176 * @param pluginNode Plugin to install
178 public static boolean prepareToInstall (PluginNode pluginNode
) throws IOException
{
179 return prepareToInstall(pluginNode
, null);
182 public static void prepareToUninstall (PluginId pluginId
) throws IOException
{
183 synchronized (PluginManager
.lock
) {
184 if (PluginManager
.isPluginInstalled(pluginId
)) {
185 // add command to delete the 'action script' file
186 IdeaPluginDescriptor pluginDescriptor
= PluginManager
.getPlugin(pluginId
);
188 StartupActionScriptManager
.ActionCommand deleteOld
= new StartupActionScriptManager
.DeleteCommand(pluginDescriptor
.getPath());
189 StartupActionScriptManager
.addActionCommand(deleteOld
);