blob: c03eca88ade321b662e57d3264e7872b7d82b348 [file] [log] [blame]
/*
* Copyright 2000-2013 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.plugins;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.BuildNumber;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.net.HttpConfigurable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.zip.GZIPInputStream;
/**
* @author stathik
* @since Mar 28, 2003
*/
public class RepositoryHelper {
@NonNls public static final String PLUGIN_LIST_FILE = "availables.xml";
public static List<IdeaPluginDescriptor> loadPluginsFromRepository(@Nullable ProgressIndicator indicator) throws Exception {
return loadPluginsFromRepository(indicator, null);
}
public static List<IdeaPluginDescriptor> loadPluginsFromRepository(@Nullable ProgressIndicator indicator,
BuildNumber buildnumber) throws Exception {
ApplicationInfoEx appInfo = ApplicationInfoImpl.getShadowInstance();
String url = appInfo.getPluginsListUrl() + "?build=" + (buildnumber != null ? buildnumber.asString() : appInfo.getApiVersion());
if (indicator != null) {
indicator.setText2(IdeBundle.message("progress.connecting.to.plugin.manager", appInfo.getPluginManagerUrl()));
}
File pluginListFile = new File(PathManager.getPluginsPath(), PLUGIN_LIST_FILE);
if (pluginListFile.length() > 0) {
try {
url = url + "&crc32=" + Files.hash(pluginListFile, Hashing.crc32()).toString();
}
catch (NoSuchMethodError e) {
String guavaPath = PathUtil.getJarPathForClass(Hashing.class);
throw new RuntimeException(guavaPath, e);
}
}
HttpURLConnection connection = ApplicationManager.getApplication() != null ?
HttpConfigurable.getInstance().openHttpConnection(url) :
(HttpURLConnection)new URL(url).openConnection();
connection.setRequestProperty("Accept-Encoding", "gzip");
connection.setReadTimeout(HttpConfigurable.CONNECTION_TIMEOUT);
connection.setConnectTimeout(HttpConfigurable.CONNECTION_TIMEOUT);
if (indicator != null) {
indicator.setText2(IdeBundle.message("progress.waiting.for.reply.from.plugin.manager", appInfo.getPluginManagerUrl()));
}
connection.connect();
try {
if (indicator != null) {
indicator.checkCanceled();
}
if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
return loadPluginList(pluginListFile);
}
String encoding = connection.getContentEncoding();
InputStream is = connection.getInputStream();
try {
if ("gzip".equalsIgnoreCase(encoding)) {
is = new GZIPInputStream(is);
}
if (indicator != null) {
indicator.setText2(IdeBundle.message("progress.downloading.list.of.plugins"));
}
return readPluginsStream(is, indicator, PLUGIN_LIST_FILE);
}
finally {
is.close();
}
}
finally {
connection.disconnect();
}
}
private synchronized static List<IdeaPluginDescriptor> readPluginsStream(InputStream is,
ProgressIndicator indicator,
String file) throws Exception {
File temp = createLocalPluginsDescriptions(file);
OutputStream os = new FileOutputStream(temp, false);
try {
byte[] buffer = new byte[1024];
int size;
while ((size = is.read(buffer)) > 0) {
os.write(buffer, 0, size);
if (indicator != null) {
indicator.checkCanceled();
}
}
}
finally {
os.close();
}
return loadPluginList(temp);
}
private static List<IdeaPluginDescriptor> loadPluginList(File file) throws Exception {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
RepositoryContentHandler handler = new RepositoryContentHandler();
parser.parse(file, handler);
return handler.getPluginsList();
}
private static File createLocalPluginsDescriptions(String file) throws IOException {
File basePath = new File(PathManager.getPluginsPath());
if (!basePath.isDirectory() && !basePath.mkdirs()) {
throw new IOException("Cannot create directory: " + basePath);
}
File temp = new File(basePath, file);
if (temp.exists()) {
FileUtil.delete(temp);
}
FileUtil.createIfDoesntExist(temp);
return temp;
}
public static List<IdeaPluginDescriptor> loadPluginsFromDescription(InputStream is, ProgressIndicator indicator) throws Exception {
try {
return readPluginsStream(is, indicator, "host.xml");
}
finally {
is.close();
}
}
public static String getDownloadUrl() {
return ApplicationInfoImpl.getShadowInstance().getPluginsDownloadUrl() + "?action=download&id=";
}
}