Google App Engine: support for EAR application in 'New Project Wizard'

This commit is contained in:
nik
2014-09-19 09:43:19 +04:00
parent d935ddc83b
commit 6452330b34
11 changed files with 86 additions and 42 deletions
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<appengine-application xmlns="http://appengine.google.com/ns/1.0">
<application></application>
</appengine-application>
@@ -0,0 +1,13 @@
<html>
<body>
<table border="0" cellpadding="2" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr>
<td colspan="3">
<font face="verdana" size="-1">
This is a built-in template used to create <b>appengine-application.xml</b> descriptor for Google App Engine application
</font>
</td>
</tr>
</table>
</body>
</html>
@@ -50,6 +50,7 @@ import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.HyperlinkLabel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jps.appengine.model.PersistenceApi;
import javax.swing.*;
@@ -82,14 +83,14 @@ public class AppEngineSupportProvider extends FacetBasedFrameworkSupportProvider
}
@Nullable
private VirtualFile createFileFromTemplate(final String templateName, final VirtualFile parent, final String fileName) {
public static VirtualFile createFileFromTemplate(final String templateName, final VirtualFile parent, final String fileName) {
parent.refresh(false, false);
final FileTemplate template = FileTemplateManager.getInstance().getJ2eeTemplate(templateName);
try {
final String text = template.getText(FileTemplateManager.getInstance().getDefaultProperties());
VirtualFile file = parent.findChild(fileName);
if (file == null) {
file = parent.createChildData(this, fileName);
file = parent.createChildData(AppEngineSupportProvider.class, fileName);
}
VfsUtil.saveText(file, text);
return file;
@@ -100,33 +101,38 @@ public class AppEngineSupportProvider extends FacetBasedFrameworkSupportProvider
}
}
private void addSupport(final Module module, final ModifiableRootModel rootModel, String sdkPath, @Nullable PersistenceApi persistenceApi) {
private void addSupport(final Module module,
final ModifiableRootModel rootModel,
FrameworkSupportModel frameworkSupportModel,
String sdkPath,
@Nullable PersistenceApi persistenceApi) {
super.addSupport(module, rootModel, null, null);
final AppEngineFacet appEngineFacet = AppEngineFacet.getAppEngineFacetByModule(module);
LOG.assertTrue(appEngineFacet != null);
AppEngineWebIntegration webIntegration = AppEngineWebIntegration.getInstance();
webIntegration.registerFrameworkInModel(frameworkSupportModel, appEngineFacet);
final AppEngineFacetConfiguration facetConfiguration = appEngineFacet.getConfiguration();
facetConfiguration.setSdkHomePath(sdkPath);
final AppEngineSdk sdk = appEngineFacet.getSdk();
final Artifact artifact = findOrCreateArtifact(appEngineFacet);
final Artifact webArtifact = findOrCreateWebArtifact(appEngineFacet);
AppEngineWebIntegration webIntegration = AppEngineWebIntegration.getInstance();
final VirtualFile descriptorDir = webIntegration.suggestParentDirectoryForAppEngineWebXml(module, rootModel);
if (descriptorDir != null) {
VirtualFile descriptor = createFileFromTemplate(AppEngineTemplateGroupDescriptorFactory.APP_ENGINE_WEB_XML_TEMPLATE, descriptorDir,
final VirtualFile webDescriptorDir = webIntegration.suggestParentDirectoryForAppEngineWebXml(module, rootModel);
if (webDescriptorDir != null) {
VirtualFile descriptor = createFileFromTemplate(AppEngineTemplateGroupDescriptorFactory.APP_ENGINE_WEB_XML_TEMPLATE, webDescriptorDir,
AppEngineUtil.APP_ENGINE_WEB_XML_NAME);
if (descriptor != null) {
webIntegration.addDescriptor(artifact, module.getProject(), descriptor);
webIntegration.addDescriptor(webArtifact, module.getProject(), descriptor);
}
}
final Project project = module.getProject();
webIntegration.setupRunConfiguration(sdk, artifact, project);
webIntegration.addDevServerToModuleDependencies(rootModel, sdk);
final Library apiJar = addProjectLibrary(module, "AppEngine API", sdk.getUserLibraryPaths(), VirtualFile.EMPTY_ARRAY);
rootModel.addLibraryEntry(apiJar);
webIntegration.addLibraryToArtifact(apiJar, artifact, project);
webIntegration.addLibraryToArtifact(apiJar, webArtifact, project);
if (persistenceApi != null) {
facetConfiguration.setRunEnhancerOnMake(true);
@@ -157,27 +163,25 @@ public class AppEngineSupportProvider extends FacetBasedFrameworkSupportProvider
}
final Library library = addProjectLibrary(module, "AppEngine ORM", Collections.singletonList(sdk.getOrmLibDirectoryPath()), sdk.getOrmLibSources());
rootModel.addLibraryEntry(library);
webIntegration.addLibraryToArtifact(library, artifact, project);
webIntegration.addLibraryToArtifact(library, webArtifact, project);
}
}
@NotNull
private static Artifact findOrCreateArtifact(AppEngineFacet appEngineFacet) {
private static Artifact findOrCreateWebArtifact(AppEngineFacet appEngineFacet) {
Module module = appEngineFacet.getModule();
List<ArtifactType> artifactTypes = AppEngineWebIntegration.getInstance().getAppEngineTargetArtifactTypes();
ArtifactType webArtifactType = AppEngineWebIntegration.getInstance().getAppEngineWebArtifactType();
final Collection<Artifact> artifacts = ArtifactUtil.getArtifactsContainingModuleOutput(module);
for (ArtifactType type : artifactTypes) {
for (Artifact artifact : artifacts) {
if (type.equals(artifact.getArtifactType())) {
return artifact;
}
for (Artifact artifact : artifacts) {
if (webArtifactType.equals(artifact.getArtifactType())) {
return artifact;
}
}
ArtifactManager artifactManager = ArtifactManager.getInstance(module.getProject());
PackagingElementFactory elementFactory = PackagingElementFactory.getInstance();
ArtifactRootElement<?> root = elementFactory.createArtifactRootElement();
elementFactory.getOrCreateDirectory(root, "WEB-INF/classes").addOrFindChild(elementFactory.createModuleOutput(module));
return artifactManager.addArtifact(module.getName(), artifactTypes.get(0), root);
return artifactManager.addArtifact(module.getName(), webArtifactType, root);
}
private static Library addProjectLibrary(final Module module, final String name, final List<String> jarDirectories, final VirtualFile[] sources) {
@@ -217,6 +221,11 @@ public class AppEngineSupportProvider extends FacetBasedFrameworkSupportProvider
return new AppEngineSupportConfigurable(model);
}
@TestOnly
public static void setSdkPath(FrameworkSupportConfigurable configurable, String path) {
((AppEngineSupportConfigurable)configurable).mySdkEditor.setPath(path);
}
private class AppEngineSupportConfigurable extends FrameworkSupportConfigurableBase implements FrameworkSupportModelListener {
private JPanel myMainPanel;
private final AppEngineSdkEditor mySdkEditor;
@@ -288,10 +297,9 @@ public class AppEngineSupportProvider extends FacetBasedFrameworkSupportProvider
@Override
public void addSupport(@NotNull Module module, @NotNull ModifiableRootModel rootModel, @Nullable Library library) {
AppEngineSupportProvider.this.addSupport(module, rootModel, mySdkEditor.getPath(), PersistenceApiComboboxUtil.getSelectedApi(myPersistenceApiComboBox));
AppEngineSupportProvider.this.addSupport(module, rootModel, myFrameworkSupportModel, mySdkEditor.getPath(), PersistenceApiComboboxUtil.getSelectedApi(myPersistenceApiComboBox));
}
@Override
public JComponent getComponent() {
return myMainPanel;
@@ -27,13 +27,16 @@ import org.jetbrains.annotations.NonNls;
*/
public class AppEngineTemplateGroupDescriptorFactory implements FileTemplateGroupDescriptorFactory {
@NonNls public static final String APP_ENGINE_WEB_XML_TEMPLATE = "AppEngineWeb.xml";
@NonNls public static final String APP_ENGINE_APPLICATION_XML_TEMPLATE = "AppEngineApplication.xml";
@NonNls public static final String APP_ENGINE_JDO_CONFIG_TEMPLATE = "AppEngineJdoConfig.xml";
@NonNls public static final String APP_ENGINE_JPA_CONFIG_TEMPLATE = "AppEngineJpaConfig.xml";
public FileTemplateGroupDescriptor getFileTemplatesDescriptor() {
final FileTemplateDescriptor appEngineXml = new FileTemplateDescriptor(APP_ENGINE_WEB_XML_TEMPLATE, StdFileTypes.XML.getIcon());
final FileTemplateDescriptor appEngineApplicationXml = new FileTemplateDescriptor(APP_ENGINE_APPLICATION_XML_TEMPLATE, StdFileTypes.XML.getIcon());
final FileTemplateDescriptor jdoConfigXml = new FileTemplateDescriptor(APP_ENGINE_JDO_CONFIG_TEMPLATE, StdFileTypes.XML.getIcon());
final FileTemplateDescriptor jpaConfigXml = new FileTemplateDescriptor(APP_ENGINE_JPA_CONFIG_TEMPLATE, StdFileTypes.XML.getIcon());
return new FileTemplateGroupDescriptor("Google App Engine", GoogleAppEngineIcons.AppEngine, appEngineXml, jdoConfigXml, jpaConfigXml);
return new FileTemplateGroupDescriptor("Google App Engine", GoogleAppEngineIcons.AppEngine, appEngineXml,
appEngineApplicationXml, jdoConfigXml, jpaConfigXml);
}
}
@@ -16,6 +16,7 @@
package com.intellij.appengine.facet;
import com.intellij.appengine.sdk.AppEngineSdk;
import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
@@ -24,6 +25,7 @@ import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.artifacts.ArtifactType;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,7 +43,15 @@ public abstract class AppEngineWebIntegration {
public abstract VirtualFile suggestParentDirectoryForAppEngineWebXml(@NotNull Module module, @NotNull ModifiableRootModel rootModel);
@NotNull
public abstract List<ArtifactType> getAppEngineTargetArtifactTypes();
public List<ArtifactType> getAppEngineTargetArtifactTypes() {
return ContainerUtil.packNullables(getAppEngineWebArtifactType(), getAppEngineApplicationArtifactType());
}
@NotNull
public abstract ArtifactType getAppEngineWebArtifactType();
@Nullable
public abstract ArtifactType getAppEngineApplicationArtifactType();
public abstract void setupJpaSupport(@NotNull Module module, @NotNull VirtualFile persistenceXml);
@@ -57,4 +67,7 @@ public abstract class AppEngineWebIntegration {
public void addDescriptor(@NotNull Artifact artifact, @NotNull Project project, @NotNull VirtualFile descriptor) {
}
public void registerFrameworkInModel(FrameworkSupportModel model, AppEngineFacet appEngineFacet) {
}
}
@@ -62,8 +62,14 @@ public class AppEngineCommunityWebIntegration extends AppEngineWebIntegration {
@NotNull
@Override
public List<ArtifactType> getAppEngineTargetArtifactTypes() {
return Collections.<ArtifactType>singletonList(PlainArtifactType.getInstance());
public ArtifactType getAppEngineWebArtifactType() {
return PlainArtifactType.getInstance();
}
@Nullable
@Override
public ArtifactType getAppEngineApplicationArtifactType() {
return null;
}
@Override
@@ -1,8 +0,0 @@
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude">
<name>Google App Engine Integration Test</name>
<id>com.intellij.appengine-test</id>
<description>
This fake plugin descriptor is used to run tests
</description>
<xi:include href="/META-INF/google-app-engine-plugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
</idea-plugin>
@@ -31,6 +31,8 @@ import com.intellij.util.CommonProcessors;
import junit.framework.Assert;
import org.jetbrains.annotations.NonNls;
import java.io.File;
/**
* @author nik
*/
@@ -50,19 +52,22 @@ public abstract class AppEngineCodeInsightTestCase extends UsefulTestCase {
new WriteAction() {
@Override
protected void run(final Result result) {
addAppEngineSupport(myProjectFixture.getModule(), DEFAULT_VERSION);
addAppEngineSupport(myProjectFixture.getModule());
}
}.execute();
}
protected abstract String getBaseDirectoryPath();
private void addAppEngineSupport(Module module, String version) {
private void addAppEngineSupport(Module module) {
final AppEngineFacet appEngine = FacetManager.getInstance(module).addFacet(AppEngineFacet.getFacetType(), "AppEngine", null);
final String sdkPath = FileUtil.toSystemIndependentName(getTestDataPath()) + "sdk/" + version;
appEngine.getConfiguration().setSdkHomePath(sdkPath);
appEngine.getConfiguration().setSdkHomePath(getSdkPath());
ModuleRootModificationUtil.addModuleLibrary(module, VirtualFileManager.constructUrl(JarFileSystem.PROTOCOL, sdkPath) + "/lib/user/orm/jdo.jar!/");
ModuleRootModificationUtil.addModuleLibrary(module, VirtualFileManager.constructUrl(JarFileSystem.PROTOCOL, getSdkPath()) + "/lib/user/orm/jdo.jar!/");
}
public static String getSdkPath() {
return FileUtil.toSystemIndependentName(new File(getTestDataPath(), "sdk/" + DEFAULT_VERSION).getAbsolutePath());
}
@Override
@@ -72,7 +77,7 @@ public abstract class AppEngineCodeInsightTestCase extends UsefulTestCase {
}
protected CodeInsightTestFixture createCodeInsightFixture(final String relativeTestDataPath) throws Exception {
final String testDataPath = getTestDataPath() + relativeTestDataPath;
final String testDataPath = new File(getTestDataPath(), relativeTestDataPath).getAbsolutePath();
final CodeInsightTestFixture codeInsightFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(myProjectFixture);
codeInsightFixture.setTestDataPath(testDataPath);
final TempDirTestFixture tempDir = codeInsightFixture.getTempDirFixture();
@@ -91,7 +96,7 @@ public abstract class AppEngineCodeInsightTestCase extends UsefulTestCase {
return codeInsightFixture;
}
private String getTestDataPath() {
return PathManagerEx.getHomePath(getClass()) + FileUtil.toSystemDependentName("/plugins/google-app-engine/testData/");
private static File getTestDataPath() {
return PathManagerEx.findFileUnderCommunityHome("plugins/google-app-engine/testData");
}
}