remote project templates

This commit is contained in:
Dmitry Avdeev
2012-11-15 16:48:49 +04:00
parent 16e304a3d8
commit 8edaebfc45
9 changed files with 225 additions and 78 deletions
@@ -25,7 +25,7 @@ import com.intellij.openapi.util.Condition;
import com.intellij.platform.DirectoryProjectGenerator;
import com.intellij.platform.ProjectTemplate;
import com.intellij.platform.ProjectTemplatesFactory;
import com.intellij.platform.templates.ArchivedProjectTemplate;
import com.intellij.platform.templates.LocalArchivedTemplate;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
@@ -70,7 +70,7 @@ public class CreateFromTemplateMode extends WizardMode {
if (templates.size() == 1 &&
!ProjectTemplatesFactory.CUSTOM_GROUP.equals(entry.getKey())) {
if (!(templates.iterator().next() instanceof ArchivedProjectTemplate)) {
if (!(templates.iterator().next() instanceof LocalArchivedTemplate)) {
sorted.putValues(ProjectTemplatesFactory.OTHER_GROUP, templates);
continue;
}
@@ -16,41 +16,25 @@
package com.intellij.platform.templates;
import com.intellij.ide.util.projectWizard.ModuleBuilder;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleTypeManager;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.platform.ProjectTemplate;
import org.jdom.Document;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* @author Dmitry Avdeev
* Date: 10/1/12
* Date: 11/14/12
*/
public class ArchivedProjectTemplate implements ProjectTemplate {
public abstract class ArchivedProjectTemplate implements ProjectTemplate {
static final String DESCRIPTION_PATH = ".idea/description.html";
private final String myDisplayName;
private final URL myArchivePath;
private final ModuleType myModuleType;
public ArchivedProjectTemplate(String displayName,
URL archivePath) {
protected final String myDisplayName;
public ArchivedProjectTemplate(String displayName) {
myDisplayName = displayName;
myArchivePath = archivePath;
myModuleType = computeModuleType(this);
}
@NotNull
@@ -59,60 +43,12 @@ public class ArchivedProjectTemplate implements ProjectTemplate {
return myDisplayName;
}
@Override
public String getDescription() {
return readEntry(new Condition<ZipEntry>() {
@Override
public boolean value(ZipEntry entry) {
return entry.getName().endsWith(DESCRIPTION_PATH);
}
});
}
@Nullable
String readEntry(Condition<ZipEntry> condition) {
ZipInputStream stream = null;
try {
stream = getStream();
ZipEntry entry;
while ((entry = stream.getNextEntry()) != null) {
if (condition.value(entry)) {
return StreamUtil.readText(stream);
}
}
}
catch (IOException e) {
return null;
}
finally {
StreamUtil.closeStream(stream);
}
return null;
}
protected abstract ModuleType getModuleType();
@NotNull
@Override
public ModuleBuilder createModuleBuilder() {
return new TemplateModuleBuilder(this, myModuleType);
}
@NotNull
private static ModuleType computeModuleType(ArchivedProjectTemplate template) {
String iml = template.readEntry(new Condition<ZipEntry>() {
@Override
public boolean value(ZipEntry entry) {
return entry.getName().endsWith(".iml");
}
});
if (iml == null) return ModuleType.EMPTY;
try {
Document document = JDOMUtil.loadDocument(iml);
String type = document.getRootElement().getAttributeValue(Module.ELEMENT_TYPE);
return ModuleTypeManager.getInstance().findByID(type);
}
catch (Exception e) {
return ModuleType.EMPTY;
}
return new TemplateModuleBuilder(this, getModuleType());
}
@Nullable
@@ -121,7 +57,5 @@ public class ArchivedProjectTemplate implements ProjectTemplate {
return null;
}
ZipInputStream getStream() throws IOException {
return new ZipInputStream(myArchivePath.openStream());
}
public abstract ZipInputStream getStream() throws IOException;
}
@@ -127,7 +127,7 @@ public class ArchivedTemplatesFactory implements ProjectTemplatesFactory {
if (child.endsWith(ZIP)) {
URL templateUrl = new URL(url.toExternalForm() + "/" + child);
String name = child.substring(0, child.length() - ZIP.length()).replace('_', ' ');
templates.add(new ArchivedProjectTemplate(name, templateUrl));
templates.add(new LocalArchivedTemplate(name, templateUrl));
}
}
}
@@ -0,0 +1,111 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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 com.intellij.platform.templates;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleTypeManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.StreamUtil;
import org.jdom.Document;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* @author Dmitry Avdeev
* Date: 10/1/12
*/
public class LocalArchivedTemplate extends ArchivedProjectTemplate {
static final String DESCRIPTION_PATH = ".idea/description.html";
private final URL myArchivePath;
private final ModuleType myModuleType;
public LocalArchivedTemplate(String displayName,
URL archivePath) {
super(displayName);
myArchivePath = archivePath;
myModuleType = computeModuleType(this);
}
@Override
public String getDescription() {
return readEntry(new Condition<ZipEntry>() {
@Override
public boolean value(ZipEntry entry) {
return entry.getName().endsWith(DESCRIPTION_PATH);
}
});
}
@Nullable
String readEntry(Condition<ZipEntry> condition) {
ZipInputStream stream = null;
try {
stream = getStream();
ZipEntry entry;
while ((entry = stream.getNextEntry()) != null) {
if (condition.value(entry)) {
return StreamUtil.readText(stream);
}
}
}
catch (IOException e) {
return null;
}
finally {
StreamUtil.closeStream(stream);
}
return null;
}
@NotNull
private static ModuleType computeModuleType(LocalArchivedTemplate template) {
String iml = template.readEntry(new Condition<ZipEntry>() {
@Override
public boolean value(ZipEntry entry) {
return entry.getName().endsWith(".iml");
}
});
if (iml == null) return ModuleType.EMPTY;
try {
Document document = JDOMUtil.loadDocument(iml);
String type = document.getRootElement().getAttributeValue(Module.ELEMENT_TYPE);
return ModuleTypeManager.getInstance().findByID(type);
}
catch (Exception e) {
return ModuleType.EMPTY;
}
}
@Override
protected ModuleType getModuleType() {
return myModuleType;
}
@Override
public ZipInputStream getStream() throws IOException {
return new ZipInputStream(myArchivePath.openStream());
}
}
@@ -0,0 +1,87 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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 com.intellij.platform.templates;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleTypeManager;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.platform.ProjectTemplate;
import com.intellij.platform.ProjectTemplatesFactory;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipInputStream;
/**
* @author Dmitry Avdeev
* Date: 11/14/12
*/
public class RemoteTemplatesFactory implements ProjectTemplatesFactory {
@NotNull
@Override
public String[] getGroups() {
return new String[] { "Samples Gallery"};
}
@NotNull
@Override
public ProjectTemplate[] createTemplates(String group, WizardContext context) {
try {
return createFromText("");
}
catch (Exception e) {
return ProjectTemplate.EMPTY_ARRAY;
}
}
public static ProjectTemplate[] createFromText(String text) throws IOException, JDOMException {
@SuppressWarnings("unchecked")
List<Element> templates = JDOMUtil.loadDocument(text).getRootElement().getChildren("template");
return ContainerUtil.map2Array(templates, ProjectTemplate.class, new Function<Element, ProjectTemplate>() {
@Override
public ProjectTemplate fun(final Element element) {
String type = element.getChildText("moduleType");
final ModuleType moduleType = ModuleTypeManager.getInstance().findByID(type);
return new ArchivedProjectTemplate(element.getChildTextTrim("name")) {
@Override
protected ModuleType getModuleType() {
return moduleType;
}
@Override
public ZipInputStream getStream() throws IOException {
return null;
}
@Nullable
@Override
public String getDescription() {
return element.getChildTextTrim("description");
}
};
}
});
}
}
@@ -98,7 +98,7 @@ public class SaveProjectAsTemplateAction extends AnAction {
}
public static VirtualFile getDescriptionFile(Project project) {
return VfsUtil.findRelativeFile(ArchivedProjectTemplate.DESCRIPTION_PATH, project.getBaseDir());
return VfsUtil.findRelativeFile(LocalArchivedTemplate.DESCRIPTION_PATH, project.getBaseDir());
}
public static void saveProject(final Project project,
@@ -127,7 +127,7 @@ public class SaveProjectAsTemplateAction extends AnAction {
final VirtualFile dir = getDirectoryToSave(project, moduleToSave);
final VirtualFile descriptionFile = getDescriptionFile(project);
if (descriptionFile == null) {
stream.putNextEntry(new ZipEntry(dir.getName() + "/" + ArchivedProjectTemplate.DESCRIPTION_PATH));
stream.putNextEntry(new ZipEntry(dir.getName() + "/" + LocalArchivedTemplate.DESCRIPTION_PATH));
stream.write(description.getBytes());
stream.closeEntry();
}
@@ -50,6 +50,7 @@ import java.util.zip.ZipInputStream;
* Date: 10/19/12
*/
public class TemplateModuleBuilder extends ModuleBuilder {
private static final NullableFunction<String,String> PATH_CONVERTOR = new NullableFunction<String, String>() {
@Nullable
@Override
@@ -57,6 +58,7 @@ public class TemplateModuleBuilder extends ModuleBuilder {
return s.contains(".idea") ? null : s;
}
};
private final ModuleType myType;
private ArchivedProjectTemplate myTemplate;
private boolean myProjectMode;
@@ -0,0 +1,10 @@
<templates>
<template>
<name>Facelets Demo</name>
<description><![CDATA[
Demonstrates IDEA support for Facelets technology
]]>
</description>
<path>facelets.zip</path>
</template>
</templates>
@@ -300,6 +300,9 @@
<projectImportProvider implementation="com.intellij.ide.util.projectWizard.ImportFromSourcesProvider"/>
<projectTemplatesFactory implementation="com.intellij.platform.templates.ArchivedTemplatesFactory"/>
<!--
<projectTemplatesFactory implementation="com.intellij.platform.templates.RemoteTemplatesFactory"/>
-->
<projectTemplatesFactory implementation="com.intellij.platform.templates.PlainModuleTemplatesFactory"/>
<applicationService serviceImplementation="com.intellij.ide.util.newProjectWizard.SelectTemplateSettings"/>