6ab678bf722c0c9283c89da166ed60afcd24a620
[idea/community.git] / platform / lang-impl / src / com / intellij / lang / javascript / boilerplate / AbstractGithubTagDownloadedProjectGenerator.java
1 package com.intellij.lang.javascript.boilerplate;
2
3 import com.intellij.ide.util.projectWizard.WebProjectTemplate;
4 import com.intellij.openapi.application.ApplicationManager;
5 import com.intellij.openapi.diagnostic.Logger;
6 import com.intellij.openapi.module.Module;
7 import com.intellij.openapi.project.Project;
8 import com.intellij.openapi.ui.Messages;
9 import com.intellij.openapi.util.io.FileUtil;
10 import com.intellij.openapi.vfs.VirtualFile;
11 import com.intellij.platform.templates.github.GeneratorException;
12 import com.intellij.platform.templates.github.GithubTagInfo;
13 import com.intellij.platform.templates.github.ZipUtil;
14 import com.intellij.util.PlatformUtils;
15 import org.jetbrains.annotations.Nls;
16 import org.jetbrains.annotations.NotNull;
17 import org.jetbrains.annotations.Nullable;
18
19 import java.io.File;
20 import java.io.UnsupportedEncodingException;
21 import java.net.URLEncoder;
22
23 /**
24  * @author Sergey Simonchik
25  */
26 public abstract class AbstractGithubTagDownloadedProjectGenerator extends WebProjectTemplate<GithubTagInfo> {
27
28   private static final Logger LOG = Logger.getInstance(AbstractGithubTagDownloadedProjectGenerator.class);
29
30   @NotNull
31   @Nls
32   @Override
33   public final String getName() {
34     return getDisplayName();
35   }
36
37   @NotNull
38   protected abstract String getDisplayName();
39
40   @NotNull
41   protected abstract String getGithubUserName();
42
43   @NotNull
44   protected abstract String getGithubRepositoryName();
45
46   @Override
47   @Nullable
48   public abstract String getDescription();
49
50   private String getTitle() {
51     return getDisplayName();
52   }
53
54   @Nullable
55   @Override
56   public String getHelpId() {
57     return "create.from.template." + getGithubUserName() + "." + getGithubRepositoryName();
58   }
59
60   @Override
61   public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
62                               @NotNull GithubTagInfo tag, @NotNull Module module) {
63     try {
64       unpackToDir(project, new File(baseDir.getPath()), tag);
65     }
66     catch (GeneratorException e) {
67       showErrorMessage(project, e.getMessage());
68     }
69     ApplicationManager.getApplication().runWriteAction(new Runnable() {
70       @Override
71       public void run() {
72         baseDir.refresh(true, true);
73       }
74     });
75   }
76
77   @NotNull
78   @Override
79   public GithubProjectGeneratorPeer createPeer() {
80     return new GithubProjectGeneratorPeer(this);
81   }
82
83   @Override
84   public boolean isPrimaryGenerator() {
85     return PlatformUtils.isWebStorm();
86   }
87
88   private void unpackToDir(@Nullable Project project,
89                            @NotNull File extractToDir,
90                            @NotNull GithubTagInfo tag) throws GeneratorException {
91     File zipArchiveFile = getCacheFile(tag);
92     String primaryUrl = getPrimaryZipArchiveUrlForDownload(tag);
93     boolean downloaded = false;
94     if (primaryUrl != null) {
95       try {
96         downloadAndUnzip(project, primaryUrl, zipArchiveFile, extractToDir, false);
97         downloaded = true;
98       } catch (GeneratorException e) {
99         LOG.info("Can't download " + primaryUrl, e);
100         FileUtil.delete(zipArchiveFile);
101       }
102     }
103     if (!downloaded) {
104       if (ApplicationManager.getApplication().isUnitTestMode()) {
105         throw new GeneratorException("Download " + tag.getZipballUrl() + " is skipped in unit test mode");
106       }
107       downloadAndUnzip(project, tag.getZipballUrl(), zipArchiveFile, extractToDir, true);
108     }
109   }
110
111   private void downloadAndUnzip(@Nullable Project project,
112                                 @NotNull String url,
113                                 @NotNull File zipArchiveFile,
114                                 @NotNull File extractToDir,
115                                 boolean retryOnError) throws GeneratorException {
116     GithubDownloadUtil.downloadContentToFileWithProgressSynchronously(
117       project,
118       url,
119       getTitle(),
120       zipArchiveFile,
121       getGithubUserName(),
122       getGithubRepositoryName(),
123       retryOnError
124     );
125     LOG.info("Content of " + url + " has been successfully downloaded to " + zipArchiveFile.getAbsolutePath()
126              + ", size " + zipArchiveFile.length() + " bytes");
127     ZipUtil.unzipWithProgressSynchronously(project, getTitle(), zipArchiveFile, extractToDir, true);
128   }
129
130   @Nullable
131   public abstract String getPrimaryZipArchiveUrlForDownload(@NotNull GithubTagInfo tag);
132
133   @NotNull
134   private File getCacheFile(@NotNull GithubTagInfo tag) {
135     String fileName = tag.getName() + ".zip";
136     try {
137       fileName = URLEncoder.encode(fileName, "UTF-8");
138     } catch (UnsupportedEncodingException e) {
139       LOG.warn("Can't urlEncode", e);
140     }
141     return GithubDownloadUtil.findCacheFile(getGithubUserName(), getGithubRepositoryName(), fileName);
142   }
143
144   private void showErrorMessage(@NotNull Project project, @NotNull String message) {
145     String fullMessage = "Error creating " + getDisplayName() + " project. " + message;
146     String title = "Create " + getDisplayName() + " Project";
147     Messages.showErrorDialog(project, fullMessage, title);
148   }
149
150 }