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