diff --git a/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java index 33b6d84e594c..67fb5a354d00 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java +++ b/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java @@ -22,12 +22,15 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.ModuleTypeManager; +import com.intellij.openapi.util.ClearableLazyValue; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.io.StreamUtil; import com.intellij.platform.ProjectTemplate; import com.intellij.platform.ProjectTemplatesFactory; +import com.intellij.util.ArrayUtil; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; import com.intellij.util.net.HttpConfigurable; import org.jdom.Element; import org.jdom.JDOMException; @@ -37,6 +40,7 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; +import java.util.Collection; import java.util.List; import java.util.zip.ZipInputStream; @@ -47,32 +51,46 @@ import java.util.zip.ZipInputStream; public class RemoteTemplatesFactory extends ProjectTemplatesFactory { private static final String URL = "http://download.jetbrains.com/idea/project_templates/"; + private static final String SAMPLES_GALLERY = "Samples Gallery"; + private final ClearableLazyValue> myTemplates = new ClearableLazyValue>() { + @NotNull + @Override + protected MultiMap compute() { + return getTemplates(); + } + }; @NotNull @Override public String[] getGroups() { - return new String[] { "Samples Gallery"}; + myTemplates.drop(); + return ArrayUtil.toStringArray(myTemplates.getValue().keySet()); } @NotNull @Override public ProjectTemplate[] createTemplates(String group, WizardContext context) { + Collection templates = myTemplates.getValue().get(group); + return templates.toArray(new ProjectTemplate[templates.size()]); + } + + private static MultiMap getTemplates() { InputStream stream = null; HttpURLConnection connection = null; String code = ApplicationInfo.getInstance().getBuild().getProductCode(); try { connection = getConnection(code + "_templates.xml"); stream = connection.getInputStream(); - String text = StreamUtil.readText(stream); + String text = StreamUtil.readText(stream, TemplateModuleBuilder.UTF_8); return createFromText(text); } catch (IOException ex) { // timeouts, lost connection etc LOG.info(ex); - return ProjectTemplate.EMPTY_ARRAY; + return MultiMap.emptyInstance(); } catch (Exception e) { LOG.error(e); - return ProjectTemplate.EMPTY_ARRAY; + return MultiMap.emptyInstance(); } finally { StreamUtil.closeStream(stream); @@ -83,11 +101,28 @@ public class RemoteTemplatesFactory extends ProjectTemplatesFactory { } @SuppressWarnings("unchecked") - public static ProjectTemplate[] createFromText(String text) throws IOException, JDOMException { + public static MultiMap createFromText(String text) throws IOException, JDOMException { - List elements = JDOMUtil.loadDocument(text).getRootElement().getChildren("template"); + Element rootElement = JDOMUtil.loadDocument(text).getRootElement(); + List groups = rootElement.getChildren("group"); + MultiMap map = new MultiMap(); + if (groups.isEmpty()) { // sample gallery by default + map.put(SAMPLES_GALLERY, createGroupTemplates(rootElement)); + } + else { + for (Element group : groups) { + map.put(group.getChildText("name"), createGroupTemplates(group)); + } + } - List templates = ContainerUtil.mapNotNull(elements, new NullableFunction() { + return map; + } + + @SuppressWarnings("unchecked") + private static List createGroupTemplates(Element groupElement) { + List elements = groupElement.getChildren("template"); + + return ContainerUtil.mapNotNull(elements, new NullableFunction() { @Override public ProjectTemplate fun(final Element element) { @@ -127,7 +162,6 @@ public class RemoteTemplatesFactory extends ProjectTemplatesFactory { }; } }); - return templates.toArray(new ProjectTemplate[templates.size()]); } private static HttpURLConnection getConnection(String path) throws IOException {