mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Allow to set up plugins from file:// filesystem
This commit is contained in:
+68
-85
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,18 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* User: anna
|
||||
* Date: 10-Aug-2007
|
||||
*/
|
||||
package com.intellij.openapi.updateSettings.impl;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.ide.plugins.RepositoryHelper;
|
||||
import com.intellij.ide.startup.StartupActionScriptManager;
|
||||
import com.intellij.openapi.application.ApplicationInfo;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -41,15 +35,17 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.io.UrlConnectionUtil;
|
||||
import com.intellij.util.io.ZipUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.URLConnection;
|
||||
|
||||
/**
|
||||
* @author anna
|
||||
* Date: 10-Aug-2007
|
||||
*/
|
||||
public class PluginDownloader {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#" + PluginDownloader.class.getName());
|
||||
|
||||
@NonNls private static final String FILENAME = "filename=";
|
||||
@@ -143,12 +139,14 @@ public class PluginDownloader {
|
||||
}
|
||||
final BuildNumber currentBuildNumber = ApplicationInfo.getInstance().getBuild();
|
||||
String sinceBuildString = descriptor.getSinceBuild();
|
||||
final BuildNumber sinceBuild = StringUtil.isEmptyOrSpaces(sinceBuildString) ? null : BuildNumber.fromString(sinceBuildString, descriptor.getName());
|
||||
final BuildNumber sinceBuild = StringUtil.isEmptyOrSpaces(sinceBuildString)
|
||||
? null : BuildNumber.fromString(sinceBuildString, descriptor.getName());
|
||||
if (sinceBuild != null && sinceBuild.compareTo(currentBuildNumber) > 0) {
|
||||
return false;
|
||||
}
|
||||
String untilBuildString = descriptor.getUntilBuild();
|
||||
final BuildNumber untilBuild = StringUtil.isEmptyOrSpaces(untilBuildString) ? null : BuildNumber.fromString(untilBuildString, descriptor.getName());
|
||||
final BuildNumber untilBuild = StringUtil.isEmptyOrSpaces(untilBuildString)
|
||||
? null : BuildNumber.fromString(untilBuildString, descriptor.getName());
|
||||
if (untilBuild != null && untilBuild.compareTo(currentBuildNumber) < 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -190,85 +188,85 @@ public class PluginDownloader {
|
||||
StartupActionScriptManager.addActionCommand(deleteTemp);
|
||||
}
|
||||
|
||||
private File downloadPlugin(ProgressIndicator pi) throws IOException {
|
||||
HttpURLConnection connection = (HttpURLConnection)new URL(myPluginUrl).openConnection();
|
||||
try
|
||||
{
|
||||
pi.setText(IdeBundle.message("progress.connecting"));
|
||||
private File downloadPlugin(final ProgressIndicator pi) throws IOException {
|
||||
final File pluginsTemp = new File(PathManager.getPluginTempPath());
|
||||
if (!pluginsTemp.exists() && !pluginsTemp.mkdirs()) {
|
||||
throw new IOException(IdeBundle.message("error.cannot.create.temp.dir", pluginsTemp));
|
||||
}
|
||||
final File file = FileUtil.createTempFile(pluginsTemp, "plugin", "download", true, false);
|
||||
|
||||
InputStream is = UrlConnectionUtil.getConnectionInputStream(connection, pi);
|
||||
pi.setText(IdeBundle.message("progress.connecting"));
|
||||
|
||||
final URLConnection connection = new URL(myPluginUrl).openConnection();
|
||||
try {
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
final int responseCode = ((HttpURLConnection)connection).getResponseCode();
|
||||
if (responseCode != HttpURLConnection.HTTP_OK) {
|
||||
throw new IOException(IdeBundle.message("error.connection.failed.with.http.code.N", responseCode));
|
||||
}
|
||||
}
|
||||
|
||||
final InputStream is = UrlConnectionUtil.getConnectionInputStream(connection, pi);
|
||||
if (is == null) {
|
||||
throw new IOException("Failed to open connection");
|
||||
}
|
||||
|
||||
pi.setText(IdeBundle.message("progress.downloading.plugin", getPluginName()));
|
||||
|
||||
final File pluginsTemp = new File(PathManager.getPluginTempPath());
|
||||
|
||||
if (!pluginsTemp.exists()) {
|
||||
pluginsTemp.mkdirs();
|
||||
}
|
||||
|
||||
File file = FileUtil.createTempFile(pluginsTemp, "plugin", "download", true, false);
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
switch (responseCode) {
|
||||
case HttpURLConnection.HTTP_OK:
|
||||
break;
|
||||
default:
|
||||
// some problems
|
||||
throw new IOException(IdeBundle.message("error.connection.failed.with.http.code.N", responseCode));
|
||||
}
|
||||
|
||||
pi.setIndeterminate(connection.getContentLength() == -1);
|
||||
|
||||
OutputStream fos = null;
|
||||
try {
|
||||
fos = new BufferedOutputStream(new FileOutputStream(file, false));
|
||||
StreamUtil.copyStreamContent(is, fos);
|
||||
}
|
||||
finally {
|
||||
if (fos != null) {
|
||||
final OutputStream fos = new BufferedOutputStream(new FileOutputStream(file, false));
|
||||
try {
|
||||
StreamUtil.copyStreamContent(is, fos);
|
||||
}
|
||||
finally {
|
||||
fos.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
if (myFileName == null) {
|
||||
String contentDisposition = connection.getHeaderField("Content-Disposition");
|
||||
if (contentDisposition == null || contentDisposition.indexOf(FILENAME) < 0) {
|
||||
// try to find filename in URL
|
||||
String usedURL = connection.getURL().toString();
|
||||
int startPos = usedURL.lastIndexOf("/");
|
||||
|
||||
myFileName = usedURL.substring(startPos + 1);
|
||||
if (myFileName.length() == 0 || myFileName.contains("?")) {
|
||||
myFileName = myPluginUrl.substring(myPluginUrl.lastIndexOf("/") + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int startIdx = contentDisposition.indexOf(FILENAME);
|
||||
myFileName = contentDisposition.substring(startIdx + FILENAME.length(), contentDisposition.length());
|
||||
// according to the HTTP spec, the filename is a quoted string, but some servers don't quote it
|
||||
// for example: http://www.jspformat.com/Download.do?formAction=d&id=8
|
||||
if (myFileName.startsWith("\"") && myFileName.endsWith("\"")) {
|
||||
myFileName = myFileName.substring(1, myFileName.length()-1);
|
||||
}
|
||||
if (myFileName.indexOf('\\') >= 0 || myFileName.indexOf('/') >= 0 || myFileName.indexOf(File.separatorChar) >= 0 ||
|
||||
myFileName.indexOf('\"') >= 0) {
|
||||
// invalid path name passed by the server - fail to download
|
||||
FileUtil.delete(file);
|
||||
throw new IOException("Invalid filename returned by server");
|
||||
}
|
||||
}
|
||||
if (myFileName == null) {
|
||||
guessFileName(connection, file);
|
||||
}
|
||||
|
||||
File newFile = new File (file.getParentFile(), myFileName);
|
||||
final File newFile = new File(file.getParentFile(), myFileName);
|
||||
FileUtil.rename(file, newFile);
|
||||
return newFile;
|
||||
}
|
||||
finally {
|
||||
connection.disconnect();
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
((HttpURLConnection)connection).disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void guessFileName(final URLConnection connection, final File file) throws IOException {
|
||||
String contentDisposition = connection.getHeaderField("Content-Disposition");
|
||||
if (contentDisposition == null || !contentDisposition.contains(FILENAME)) {
|
||||
// try to find filename in URL
|
||||
String usedURL = connection.getURL().toString();
|
||||
int startPos = usedURL.lastIndexOf("/");
|
||||
myFileName = usedURL.substring(startPos + 1);
|
||||
if (myFileName.length() == 0 || myFileName.contains("?")) {
|
||||
myFileName = myPluginUrl.substring(myPluginUrl.lastIndexOf("/") + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int startIdx = contentDisposition.indexOf(FILENAME);
|
||||
myFileName = contentDisposition.substring(startIdx + FILENAME.length(), contentDisposition.length());
|
||||
// according to the HTTP spec, the filename is a quoted string, but some servers don't quote it
|
||||
// for example: http://www.jspformat.com/Download.do?formAction=d&id=8
|
||||
if (myFileName.startsWith("\"") && myFileName.endsWith("\"")) {
|
||||
myFileName = myFileName.substring(1, myFileName.length() - 1);
|
||||
}
|
||||
if (myFileName.indexOf('\\') >= 0 || myFileName.indexOf('/') >= 0 || myFileName.indexOf(File.separatorChar) >= 0 ||
|
||||
myFileName.indexOf('\"') >= 0) {
|
||||
// invalid path name passed by the server - fail to download
|
||||
FileUtil.delete(file);
|
||||
throw new IOException("Invalid filename returned by server");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,19 +291,4 @@ public class PluginDownloader {
|
||||
public String getPluginVersion() {
|
||||
return myPluginVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates given plugin from Repository
|
||||
* @param pluginId given plugin id
|
||||
* @param pluginVersion available version or null if plugin must be uploaded even if current version is greater than uploading
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void updateFromRepository(final String pluginId, final @Nullable String pluginVersion) throws IOException {
|
||||
@NonNls final String url =
|
||||
RepositoryHelper.DOWNLOAD_URL + URLEncoder.encode(pluginId, "UTF8") + "&build=" + ApplicationInfo.getInstance().getBuild().asString();
|
||||
final PluginDownloader downloader = new PluginDownloader(pluginId, url, pluginVersion);
|
||||
if (downloader.prepareToInstall()) {
|
||||
downloader.install();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+39
-34
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,15 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: mike
|
||||
* Date: Oct 31, 2002
|
||||
* Time: 6:33:01 PM
|
||||
* To change template for new class use
|
||||
* Code Style | Class Templates options (Tools | IDE Options).
|
||||
*/
|
||||
package com.intellij.openapi.updateSettings.impl;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
@@ -44,9 +35,9 @@ import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.ex.http.HttpFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.UrlConnectionUtil;
|
||||
@@ -72,15 +63,20 @@ import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* XML sample:
|
||||
* <pre>{@code
|
||||
* <idea>
|
||||
* <build>456</build>
|
||||
* <version>4.5.2</version>
|
||||
* <title>New Intellij IDEA Version</title>
|
||||
* <message>
|
||||
* New version of IntelliJ IDEA is available.
|
||||
* Please visit http://www.intellij.com/ for more info.
|
||||
* </message>
|
||||
* <build>456</build>
|
||||
* <version>4.5.2</version>
|
||||
* <title>New Intellij IDEA Version</title>
|
||||
* <message>
|
||||
* New version of IntelliJ IDEA is available.
|
||||
* Please visit http://www.intellij.com/ for more info.
|
||||
* </message>
|
||||
* </idea>
|
||||
* }</pre>
|
||||
*
|
||||
* @author mike
|
||||
* Date: Oct 31, 2002
|
||||
*/
|
||||
public final class UpdateChecker {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.updateSettings.impl.UpdateChecker");
|
||||
@@ -110,6 +106,7 @@ public final class UpdateChecker {
|
||||
private static class StringHolder {
|
||||
private static final String UPDATE_URL = ApplicationInfoEx.getInstanceEx().getUpdateUrls().getCheckingUrl();
|
||||
private static final String PATCHES_URL = ApplicationInfoEx.getInstanceEx().getUpdateUrls().getPatchesUrl();
|
||||
private StringHolder() { }
|
||||
}
|
||||
|
||||
private static String getUpdateUrl() {
|
||||
@@ -190,12 +187,14 @@ public final class UpdateChecker {
|
||||
public static boolean checkPluginsHost(final String host, final List<PluginDownloader> downloaded) throws Exception {
|
||||
final Document document = loadVersionInfo(host);
|
||||
if (document == null) return false;
|
||||
|
||||
boolean success = true;
|
||||
for (Object plugin : document.getRootElement().getChildren("plugin")) {
|
||||
Element pluginElement = (Element)plugin;
|
||||
final Element pluginElement = (Element)plugin;
|
||||
final String pluginId = pluginElement.getAttributeValue("id");
|
||||
String pluginUrl = pluginElement.getAttributeValue("url");
|
||||
final String pluginUrl = pluginElement.getAttributeValue("url");
|
||||
final String pluginVersion = pluginElement.getAttributeValue("version");
|
||||
|
||||
if (pluginId == null) {
|
||||
LOG.info("plugin id should not be null");
|
||||
success = false;
|
||||
@@ -208,19 +207,25 @@ public final class UpdateChecker {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!pluginUrl.startsWith(HttpFileSystem.PROTOCOL)) {
|
||||
final HttpFileSystem fileSystem = HttpFileSystem.getInstance();
|
||||
final VirtualFile hostFile = fileSystem.findFileByPath(VfsUtil.urlToPath(host));
|
||||
LOG.assertTrue(hostFile != null);
|
||||
final VirtualFile pluginByRelativePath = findPluginByRelativePath(hostFile.getParent(), pluginUrl, fileSystem);
|
||||
if (pluginByRelativePath != null) {
|
||||
pluginUrl = pluginByRelativePath.getUrl();
|
||||
final VirtualFileManager fileManager = VirtualFileManager.getInstance();
|
||||
VirtualFile pluginFile = fileManager.findFileByUrl(pluginUrl);
|
||||
if (pluginFile == null) {
|
||||
final VirtualFile hostFile = fileManager.findFileByUrl(host);
|
||||
if (hostFile == null) {
|
||||
LOG.error("can't find file by url '" + host + "'");
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
pluginFile = findPluginByRelativePath(hostFile.getParent(), pluginUrl, hostFile.getFileSystem());
|
||||
if (pluginFile == null) {
|
||||
LOG.error("can't find '" + pluginUrl + "' relative to '" + host + "'");
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
final String finalPluginUrl = pluginUrl;
|
||||
Runnable updatePluginRunnable = new Runnable() {
|
||||
final String finalPluginUrl = pluginFile.getUrl();
|
||||
final Runnable updatePluginRunnable = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
@@ -248,9 +253,9 @@ public final class UpdateChecker {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile findPluginByRelativePath(VirtualFile hostFile,
|
||||
@NotNull @NonNls String relPath,
|
||||
final HttpFileSystem fileSystem) {
|
||||
public static VirtualFile findPluginByRelativePath(@NotNull final VirtualFile hostFile,
|
||||
@NotNull @NonNls final String relPath,
|
||||
@NotNull final VirtualFileSystem fileSystem) {
|
||||
if (relPath.length() == 0) return hostFile;
|
||||
int index = relPath.indexOf('/');
|
||||
if (index < 0) index = relPath.length();
|
||||
|
||||
@@ -512,6 +512,7 @@ plugin.status.installed=Installed
|
||||
progress.waiting.for.reply.from.plugin.manager=Waiting for reply from {0}
|
||||
progress.connecting=Connecting...
|
||||
progress.downloading.plugin=Downloading plugin ''{0}''
|
||||
error.cannot.create.temp.dir=Unable to create temp directory ''{0}''
|
||||
error.connection.failed.with.http.code.N=Connection failed with HTTP code {0}
|
||||
progress.connecting.to.plugin.manager=Connecting to {0}
|
||||
label.plugin.vendor.email=E-mail:
|
||||
|
||||
Reference in New Issue
Block a user