blob: fd064347c71fda57e6ecf9d3a4bab59deec0e21d [file] [log] [blame]
/*
* Copyright 2005 Sascha Weinreuter
*
* 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 org.intellij.lang.xpath.xslt.quickfix;
import com.intellij.javaee.ExternalResourceManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.net.NetUtils;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URLConnection;
import java.util.Set;
@SuppressWarnings({"StringEquality"})
public abstract class DownloadManager {
private static final ExternalResourceManager resourceManager = ExternalResourceManager.getInstance();
private final Project myProject;
private final ProgressIndicator myProgress;
private final String myResourcePath;
public DownloadManager(Project project, ProgressIndicator progress) {
myProject = project;
myProgress = progress;
myResourcePath = PathManager.getSystemPath() + File.separatorChar + "extResources";
final File dir = new File(myResourcePath);
dir.mkdirs();
}
public void fetch(String location) throws DownloadException {
if (resourceManager.getResourceLocation(location) == location) {
myProgress.setText("Downloading " + location);
downloadAndRegister(location);
}
}
private void downloadAndRegister(final String location) throws DownloadException {
final ExternalResourceManager resourceManager = ExternalResourceManager.getInstance();
File file = null;
try {
final URLConnection urlConnection = HttpConfigurable.getInstance().openConnection(location);
urlConnection.connect();
final InputStream in = urlConnection.getInputStream();
final OutputStream out;
try {
final int total = urlConnection.getContentLength();
final String name = Integer.toHexString(System.identityHashCode(this)) +
"_" +
Integer.toHexString(location.hashCode()) +
"_" +
location.substring(location.lastIndexOf('/') + 1);
file = new File(myResourcePath, name.lastIndexOf('.') == -1 ? name + ".xml" : name);
out = new FileOutputStream(file);
try {
NetUtils.copyStreamContent(myProgress, in, out, total);
}
finally {
out.close();
}
}
finally {
in.close();
}
try {
final File _file = file;
//noinspection unchecked
final Set<String>[] resourceDependencies = new Set[1];
new WriteAction() {
@Override
protected void run(Result result) throws Throwable {
final VirtualFile vf = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(_file);
if (vf != null) {
final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vf);
if (psiFile != null && isAccepted(psiFile)) {
resourceDependencies[0] = getResourceDependencies(psiFile);
resourceManager.addResource(location, _file.getAbsolutePath());
}
else {
ApplicationManager.getApplication().invokeLater(
new Runnable() {
@Override
public void run() {
Messages.showErrorDialog(myProject, "Not a valid file: " + vf.getPresentableUrl(), "Download Problem");
}
}, myProject.getDisposed());
}
}
}
}.execute();
if (resourceDependencies[0] != null) {
for (String s : resourceDependencies[0]) {
myProgress.checkCanceled();
myProgress.setFraction(0);
fetch(s);
}
}
}
catch (Error err) {
Throwable e = err.getCause();
if (e instanceof InterruptedException) {
// OK
}
else if (e instanceof InvocationTargetException) {
final Throwable targetException = ((InvocationTargetException)e).getTargetException();
if (targetException instanceof RuntimeException) {
throw (RuntimeException)targetException;
}
else if (targetException instanceof IOException) {
throw (IOException)targetException;
}
else if (targetException instanceof InterruptedException) {
// OK
}
else {
Logger.getInstance(getClass().getName()).error(e);
}
}
else {
throw err;
}
}
}
catch (IOException e) {
throw new DownloadException(location, e);
}
finally {
if (file != null && resourceManager.getResourceLocation(location) == location) {
// something went wrong. get rid of the file
file.delete();
}
}
}
protected abstract boolean isAccepted(PsiFile psiFile);
protected abstract Set<String> getResourceDependencies(PsiFile psiFile);
public static class DownloadException extends IOException {
private final String myLocation;
public DownloadException(String location, IOException cause) {
super();
myLocation = location;
initCause(cause);
}
public String getLocation() {
return myLocation;
}
}
}