org.intellij.lang.xpath.xslt.quickfix.DownloadManager.java Source code

Java tutorial

Introduction

Here is the source code for org.intellij.lang.xpath.xslt.quickfix.DownloadManager.java

Source

/*
 * 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 java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;

import org.jetbrains.annotations.NotNull;
import com.intellij.javaee.ExternalResourceManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
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.util.io.FileUtil;
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.io.HttpRequests;

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";
        //noinspection ResultOfMethodCallIgnored
        new File(myResourcePath).mkdirs();
    }

    public void fetch(@NotNull final String location) throws DownloadException {
        if (resourceManager.getResourceLocation(location, myProject) != location) {
            return;
        }

        myProgress.setText("Downloading " + location);

        File file = null;
        try {
            file = HttpRequests.request(location).connect(new HttpRequests.RequestProcessor<File>() {
                @Override
                public File process(@NotNull HttpRequests.Request request) throws IOException {
                    String name = Integer.toHexString(System.identityHashCode(this)) + "_"
                            + Integer.toHexString(location.hashCode()) + "_"
                            + location.substring(location.lastIndexOf('/') + 1);
                    return request.saveToFile(
                            new File(myResourcePath, name.lastIndexOf('.') == -1 ? name + ".xml" : name),
                            myProgress);
                }
            });

            try {
                //noinspection unchecked
                final Set<String>[] resourceDependencies = new Set[1];
                final VirtualFile vf = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
                if (vf != null) {
                    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(
                                () -> Messages.showErrorDialog(myProject,
                                        "Not a valid file: " + vf.getPresentableUrl(), "Download Problem"),
                                myProject.getDisposed());
                    }
                }

                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 InvocationTargetException) {
                    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)) {
                        Logger.getInstance(getClass().getName()).error(e);
                    }
                } else if (!(e instanceof InterruptedException)) {
                    throw err;
                }
            }
        } catch (IOException e) {
            throw new DownloadException(location, e);
        } finally {
            if (file != null && resourceManager.getResourceLocation(location, myProject) == location) {
                // something went wrong. get rid of the file
                FileUtil.delete(file);
            }
        }
    }

    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;
        }
    }
}