From 6452330b34815f5e56c1df2dc0db75bbe44195fa Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 18 Sep 2014 18:50:02 +0400 Subject: [PATCH] Google App Engine: support for EAR application in 'New Project Wizard' --- .../j2ee/AppEngineApplication.xml.ft | 4 ++ .../j2ee/AppEngineApplication.xml.html | 13 +++++ .../facet/AppEngineSupportProvider.java | 52 +++++++++++-------- ...pEngineTemplateGroupDescriptorFactory.java | 5 +- .../facet/AppEngineWebIntegration.java | 15 +++++- .../AppEngineCommunityWebIntegration.java | 10 +++- .../testData/sdk/1.3.7/bin/appcfg.bat | 0 .../testData/sdk/1.3.7/bin/appcfg.sh | 0 .../sdk/1.3.7/lib/appengine-tools-api.jar | 0 .../testSource/META-INF/plugin.xml | 8 --- .../AppEngineCodeInsightTestCase.java | 21 +++++--- 11 files changed, 86 insertions(+), 42 deletions(-) create mode 100644 plugins/google-app-engine/resources/fileTemplates/j2ee/AppEngineApplication.xml.ft create mode 100644 plugins/google-app-engine/resources/fileTemplates/j2ee/AppEngineApplication.xml.html create mode 100644 plugins/google-app-engine/testData/sdk/1.3.7/bin/appcfg.bat create mode 100644 plugins/google-app-engine/testData/sdk/1.3.7/bin/appcfg.sh create mode 100644 plugins/google-app-engine/testData/sdk/1.3.7/lib/appengine-tools-api.jar delete mode 100644 plugins/google-app-engine/testSource/META-INF/plugin.xml diff --git a/plugins/google-app-engine/resources/fileTemplates/j2ee/AppEngineApplication.xml.ft b/plugins/google-app-engine/resources/fileTemplates/j2ee/AppEngineApplication.xml.ft new file mode 100644 index 000000000000..dd9cb0ebc5d5 --- /dev/null +++ b/plugins/google-app-engine/resources/fileTemplates/j2ee/AppEngineApplication.xml.ft @@ -0,0 +1,4 @@ + + + + diff --git a/plugins/google-app-engine/resources/fileTemplates/j2ee/AppEngineApplication.xml.html b/plugins/google-app-engine/resources/fileTemplates/j2ee/AppEngineApplication.xml.html new file mode 100644 index 000000000000..65c8b91abcaa --- /dev/null +++ b/plugins/google-app-engine/resources/fileTemplates/j2ee/AppEngineApplication.xml.html @@ -0,0 +1,13 @@ + + + + + + +
+ + This is a built-in template used to create appengine-application.xml descriptor for Google App Engine application + +
+ + diff --git a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineSupportProvider.java b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineSupportProvider.java index a0ee39b0b1ae..cc6d22a2e422 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineSupportProvider.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineSupportProvider.java @@ -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 artifactTypes = AppEngineWebIntegration.getInstance().getAppEngineTargetArtifactTypes(); + ArtifactType webArtifactType = AppEngineWebIntegration.getInstance().getAppEngineWebArtifactType(); final Collection 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 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; diff --git a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineTemplateGroupDescriptorFactory.java b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineTemplateGroupDescriptorFactory.java index a1223087a1e8..4ab727d9c8e3 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineTemplateGroupDescriptorFactory.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineTemplateGroupDescriptorFactory.java @@ -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); } } diff --git a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineWebIntegration.java b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineWebIntegration.java index c5d414d2cd2f..bd4c44c87e0e 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineWebIntegration.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineWebIntegration.java @@ -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 getAppEngineTargetArtifactTypes(); + public List 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) { + } } diff --git a/plugins/google-app-engine/source/com/intellij/appengine/facet/impl/AppEngineCommunityWebIntegration.java b/plugins/google-app-engine/source/com/intellij/appengine/facet/impl/AppEngineCommunityWebIntegration.java index ad5fe5cbe39f..0631347e17a2 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/facet/impl/AppEngineCommunityWebIntegration.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/facet/impl/AppEngineCommunityWebIntegration.java @@ -62,8 +62,14 @@ public class AppEngineCommunityWebIntegration extends AppEngineWebIntegration { @NotNull @Override - public List getAppEngineTargetArtifactTypes() { - return Collections.singletonList(PlainArtifactType.getInstance()); + public ArtifactType getAppEngineWebArtifactType() { + return PlainArtifactType.getInstance(); + } + + @Nullable + @Override + public ArtifactType getAppEngineApplicationArtifactType() { + return null; } @Override diff --git a/plugins/google-app-engine/testData/sdk/1.3.7/bin/appcfg.bat b/plugins/google-app-engine/testData/sdk/1.3.7/bin/appcfg.bat new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/plugins/google-app-engine/testData/sdk/1.3.7/bin/appcfg.sh b/plugins/google-app-engine/testData/sdk/1.3.7/bin/appcfg.sh new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/plugins/google-app-engine/testData/sdk/1.3.7/lib/appengine-tools-api.jar b/plugins/google-app-engine/testData/sdk/1.3.7/lib/appengine-tools-api.jar new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/plugins/google-app-engine/testSource/META-INF/plugin.xml b/plugins/google-app-engine/testSource/META-INF/plugin.xml deleted file mode 100644 index 01deb890064a..000000000000 --- a/plugins/google-app-engine/testSource/META-INF/plugin.xml +++ /dev/null @@ -1,8 +0,0 @@ - - Google App Engine Integration Test - com.intellij.appengine-test - - This fake plugin descriptor is used to run tests - - - diff --git a/plugins/google-app-engine/testSource/com/intellij/appengine/AppEngineCodeInsightTestCase.java b/plugins/google-app-engine/testSource/com/intellij/appengine/AppEngineCodeInsightTestCase.java index a20feb04425a..333c15f743b4 100644 --- a/plugins/google-app-engine/testSource/com/intellij/appengine/AppEngineCodeInsightTestCase.java +++ b/plugins/google-app-engine/testSource/com/intellij/appengine/AppEngineCodeInsightTestCase.java @@ -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"); } }