From f90970682d52297dd7185c73eed433820cdc52c0 Mon Sep 17 00:00:00 2001 From: Brian de Alwis Date: Fri, 29 Jun 2018 16:05:50 -0400 Subject: [PATCH] Add support for YAML files for App Engine content block (#3186) --- .../AppEngineConfigurationUtilTest.java | 128 +++++++++++ ...ppEngineStandardProjectConvertJobTest.java | 5 +- .../AppEngineContentProviderTest.java | 167 ++++++++++++-- .../navigator/AppEngineLabelProviderTest.java | 216 +++++++++++------- .../facets/ui/navigator/PluginXmlTest.java | 37 ++- .../model/AppEngineProjectElementTest.java | 195 ++++++++++++++++ .../AppEngineStandardProjectElementTest.java | 91 -------- .../ui/navigator/model/ModelRefreshTests.java | 34 +-- .../plugin.xml | 20 +- .../facets/AppEngineConfigurationUtil.java | 114 +++++++++ ...ngineStandardJre7ProjectFacetDetector.java | 3 +- .../facets/StandardFacetInstallDelegate.java | 38 ++- .../navigator/AppEngineContentProvider.java | 52 +++-- .../ui/navigator/AppEngineLabelProvider.java | 80 +++---- ...ment.java => AppEngineProjectElement.java} | 165 ++++++++++--- .../ui/navigator/model/CronDescriptor.java | 3 +- .../model/DatastoreIndexesDescriptor.java | 3 +- .../model/DenialOfServiceDescriptor.java | 3 +- .../model/DispatchRoutingDescriptor.java | 3 +- .../navigator/model/TaskQueuesDescriptor.java | 3 +- .../server/DatastoreIndexUpdateData.java | 8 +- .../localserver/server/ModuleUtils.java | 5 +- .../DatastoreIndexesUpdatedStatusHandler.java | 12 +- ...pEngineStandardFacetVersionChangeTest.java | 5 +- .../java8/AppEngineWebBuilderTest.java | 13 +- .../standard/java8/ConversionTests.java | 8 +- .../AppEngineStandardFacetChangeListener.java | 5 +- ...ngineStandardJre8ProjectFacetDetector.java | 5 +- .../standard/java8/AppEngineWebBuilder.java | 5 +- .../java8/ConvertToJava8RuntimeHandler.java | 9 +- .../m2e/AppEngineStandardProjectDetector.java | 6 +- .../AppEngineWebXmlValidationTest.java | 4 +- .../test/util/project/TestProjectCreator.java | 5 +- 33 files changed, 1078 insertions(+), 372 deletions(-) create mode 100644 plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineConfigurationUtilTest.java create mode 100644 plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineProjectElementTest.java delete mode 100644 plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineStandardProjectElementTest.java create mode 100644 plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineConfigurationUtil.java rename plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/{AppEngineStandardProjectElement.java => AppEngineProjectElement.java} (63%) diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineConfigurationUtilTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineConfigurationUtilTest.java new file mode 100644 index 0000000000..122a37a265 --- /dev/null +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineConfigurationUtilTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2018 Google LLC + * + * 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.google.cloud.tools.eclipse.appengine.facets; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.tools.eclipse.test.util.project.TestProjectCreator; +import com.google.cloud.tools.eclipse.util.io.ResourceUtils; +import com.google.common.io.ByteSource; +import com.google.common.io.ByteStreams; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; +import org.eclipse.jst.common.project.facet.core.JavaFacet; +import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils; +import org.junit.Rule; +import org.junit.Test; + +public class AppEngineConfigurationUtilTest { + @Rule + public TestProjectCreator projectCreator = + new TestProjectCreator().withFacets(WebFacetUtils.WEB_31, JavaFacet.VERSION_1_8); + + @Test + public void testCreateConfigurationFile_byteContent() throws CoreException, IOException { + IFile file = + AppEngineConfigurationUtil.createConfigurationFile( + projectCreator.getProject(), + new Path("example.txt"), + new ByteArrayInputStream(new byte[] {0, 1, 2, 3}), + true, + null); + try (InputStream input = file.getContents()) { + byte[] contents = ByteStreams.toByteArray(input); + assertArrayEquals(new byte[] {0, 1, 2, 3}, contents); + } + } + + @Test + public void testCreateConfigurationFile_charContent() throws CoreException, IOException { + String original = "\u1f64c this is a test \u00b5"; + IFile file = + AppEngineConfigurationUtil.createConfigurationFile( + projectCreator.getProject(), new Path("example.txt"), original, true, null); + try (InputStream input = file.getContents()) { + String contents = new String(ByteStreams.toByteArray(input), StandardCharsets.UTF_8); + assertEquals(original, contents); + } + } + + @Test + public void testCreateConfigurationFile_noAppEngineDir() throws CoreException, IOException { + IFile file = + AppEngineConfigurationUtil.createConfigurationFile( + projectCreator.getProject(), + new Path("index.yaml"), + ByteSource.empty().openStream(), + true, + null); + assertEquals(new Path("WebContent/WEB-INF/index.yaml"), file.getProjectRelativePath()); + } + + @Test + public void testCreateConfigurationFile_withAppEngineDir() throws CoreException, IOException { + IProject project = projectCreator.getProject(); + IFolder srcMainAppengine = project.getFolder(new Path("src/main/appengine")); + ResourceUtils.createFolders(srcMainAppengine, null); + IFile file = + AppEngineConfigurationUtil.createConfigurationFile( + project, new Path("index.yaml"), ByteSource.empty().openStream(), true, null); + assertEquals(new Path("src/main/appengine/index.yaml"), file.getProjectRelativePath()); + } + + @Test + public void testFindConfigurationFile_noAppEngineDir() throws CoreException, IOException { + // ensure the configured WEB-INF directory (WebContent) is found + IProject project = projectCreator.getProject(); + assertTrue(project.getFolder("WebContent/WEB-INF").exists()); + ResourceUtils.createFolders(project.getFolder("src/main/appengine"), null); + + IFile original = project.getFile(new Path("WebContent/WEB-INF/index.yaml")); + original.create(ByteSource.empty().openStream(), true, null); + + IFile resolved = + AppEngineConfigurationUtil.findConfigurationFile(project, new Path("index.yaml")); + assertEquals(original, resolved); + } + + /** Ensure the file found in src/main/appengine wins. */ + @Test + public void testFindConfigurationFile_withAppEngineDir() throws CoreException, IOException { + IProject project = projectCreator.getProject(); + assertTrue(project.getFolder("WebContent/WEB-INF").exists()); + ResourceUtils.createFolders(project.getFolder("src/main/appengine"), null); + + project + .getFile("WebContent/WEB-INF/index.yaml") + .create(ByteSource.empty().openStream(), true, null); + IFile original = project.getFile("src/main/appengine/index.yaml"); + original.create(ByteSource.empty().openStream(), true, null); + + IFile resolved = + AppEngineConfigurationUtil.findConfigurationFile(project, new Path("index.yaml")); + assertEquals(original, resolved); + } +} diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/convert/AppEngineStandardProjectConvertJobTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/convert/AppEngineStandardProjectConvertJobTest.java index 3c29414e06..1c60392e81 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/convert/AppEngineStandardProjectConvertJobTest.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/convert/AppEngineStandardProjectConvertJobTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import com.google.cloud.tools.eclipse.test.util.ThreadDumpingWatchdog; @@ -59,7 +60,9 @@ public void testAppEngineFacetAdded() throws CoreException, InterruptedException // verify App Engine standard files are present IFile webXml = WebProjectUtil.findInWebInf(project, new Path("web.xml")); assertTrue(webXml.exists()); - assertTrue(WebProjectUtil.findInWebInf(project, new Path("appengine-web.xml")).exists()); + IFile appEngineWebXml = + AppEngineConfigurationUtil.findConfigurationFile(project, new Path("appengine-web.xml")); + assertTrue(appEngineWebXml.exists()); // verify no overlap in WEB-INF and source paths // Java 1.7 facet sets the source path to src/ which will overlap with the diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineContentProviderTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineContentProviderTest.java index c7b99b458d..73efff20a4 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineContentProviderTest.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineContentProviderTest.java @@ -28,23 +28,30 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import com.google.cloud.tools.appengine.api.AppEngineException; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; +import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineProjectElement; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineResourceElement; -import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineStandardProjectElement; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.CronDescriptor; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.DatastoreIndexesDescriptor; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.DenialOfServiceDescriptor; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.DispatchRoutingDescriptor; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.TaskQueuesDescriptor; import com.google.cloud.tools.eclipse.test.util.project.TestProjectCreator; +import com.google.common.io.ByteSource; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.function.BiConsumer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jst.common.project.facet.core.JavaFacet; import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils; @@ -93,15 +100,15 @@ public void testGetChildren_appEngineStandardProject() { Object[] children = fixture.getChildren(projectCreator.getFacetedProject()); assertNotNull(children); assertEquals(1, children.length); - assertTrue(children[0] instanceof AppEngineStandardProjectElement); + assertTrue(children[0] instanceof AppEngineProjectElement); } @Test public void testGetChildren_appEngineStandardProjectElement_noService_noChildren() throws AppEngineException { ConfigurationFileUtils.createAppEngineWebXml(projectCreator.getProject(), null); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(projectCreator.getProject()); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(projectCreator.getProject()); Object[] children = fixture.getChildren(projectElement); assertNotNull(children); @@ -114,8 +121,8 @@ public void testGetChildren_appEngineStandardProjectElement_noDefault_cronIgnore ConfigurationFileUtils.createAppEngineWebXml( projectCreator.getProject(), "service"); // $NON-NLS-1$ ConfigurationFileUtils.createEmptyCronXml(projectCreator.getProject()); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(projectCreator.getProject()); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(projectCreator.getProject()); Object[] children = fixture.getChildren(projectElement); assertNotNull(children); @@ -128,8 +135,8 @@ public void testGetChildren_appEngineStandardProjectElement_default_cron() ConfigurationFileUtils.createAppEngineWebXml( projectCreator.getProject(), "default"); // $NON-NLS-1$ ConfigurationFileUtils.createEmptyCronXml(projectCreator.getProject()); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(projectCreator.getProject()); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(projectCreator.getProject()); Object[] children = fixture.getChildren(projectElement); assertNotNull(children); @@ -147,8 +154,8 @@ public void testGetChildren_appEngineStandardProjectElement_default_dispatch() ConfigurationFileUtils.createAppEngineWebXml( projectCreator.getProject(), "default"); // $NON-NLS-1$ ConfigurationFileUtils.createEmptyDispatchXml(projectCreator.getProject()); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(projectCreator.getProject()); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(projectCreator.getProject()); Object[] children = fixture.getChildren(projectElement); assertNotNull(children); @@ -166,8 +173,8 @@ public void testGetChildren_appEngineStandardProjectElement_default_datastoreInd ConfigurationFileUtils.createAppEngineWebXml( projectCreator.getProject(), "default"); // $NON-NLS-1$ ConfigurationFileUtils.createEmptyDatastoreIndexesXml(projectCreator.getProject()); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(projectCreator.getProject()); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(projectCreator.getProject()); Object[] children = fixture.getChildren(projectElement); assertNotNull(children); @@ -185,8 +192,8 @@ public void testGetChildren_appEngineStandardProjectElement_default_denialOfServ ConfigurationFileUtils.createAppEngineWebXml( projectCreator.getProject(), "default"); // $NON-NLS-1$ ConfigurationFileUtils.createEmptyDosXml(projectCreator.getProject()); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(projectCreator.getProject()); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(projectCreator.getProject()); Object[] children = fixture.getChildren(projectElement); assertNotNull(children); @@ -204,8 +211,8 @@ public void testGetChildren_appEngineStandardProjectElement_default_taskQueue() ConfigurationFileUtils.createAppEngineWebXml( projectCreator.getProject(), "default"); // $NON-NLS-1$ ConfigurationFileUtils.createEmptyQueueXml(projectCreator.getProject()); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(projectCreator.getProject()); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(projectCreator.getProject()); Object[] children = fixture.getChildren(projectElement); assertNotNull(children); @@ -226,20 +233,20 @@ public void testHasChildren_appEngineStandardProject() { @Test public void testHasChildren_appEngineStandardProjectElement_noConfigs() { - AppEngineStandardProjectElement projectElement = mock(AppEngineStandardProjectElement.class); + AppEngineProjectElement projectElement = mock(AppEngineProjectElement.class); when(projectElement.getConfigurations()).thenReturn(new AppEngineResourceElement[0]); assertFalse(fixture.hasChildren(projectElement)); } @Test public void testHasChildren_appEngineStandardProjectElement_withConfigs() { - AppEngineStandardProjectElement projectElement = mock(AppEngineStandardProjectElement.class); + AppEngineProjectElement projectElement = mock(AppEngineProjectElement.class); when(projectElement.getConfigurations()).thenReturn(new AppEngineResourceElement[1]); assertTrue(fixture.hasChildren(projectElement)); } @Test - public void testDynamicChanges() throws CoreException { + public void testDynamicChanges_appEngineStandardJava7() throws CoreException { projectCreator.withFacets(AppEngineStandardFacet.JRE7, WebFacetUtils.WEB_25); StructuredViewer viewer = mock(StructuredViewer.class); fixture.inputChanged(viewer, null, null); // installs resource-changed listener @@ -250,8 +257,8 @@ public void testDynamicChanges() throws CoreException { Object[] children = fixture.getChildren(project); assertNotNull(children); assertEquals(1, children.length); - assertTrue(children[0] instanceof AppEngineStandardProjectElement); - AppEngineStandardProjectElement projectElement = (AppEngineStandardProjectElement) children[0]; + assertTrue(children[0] instanceof AppEngineProjectElement); + AppEngineProjectElement projectElement = (AppEngineProjectElement) children[0]; children = fixture.getChildren(projectElement); assertNotNull(children); assertEquals(0, children.length); @@ -291,6 +298,122 @@ public void testDynamicChanges() throws CoreException { assertThat(children, hasItemInArray(instanceOf(DatastoreIndexesDescriptor.class))); } + @Test + public void testDynamicChanges_appYaml() throws CoreException, IOException { + projectCreator.withFacets(AppEngineStandardFacet.JRE7, WebFacetUtils.WEB_25); + IProject project = projectCreator.getProject(); + + StructuredViewer viewer = mock(StructuredViewer.class); + fixture.inputChanged(viewer, null, null); // installs resource-changed listener + + ByteArrayInputStream stream = + new ByteArrayInputStream("runtime: java\n".getBytes(StandardCharsets.UTF_8)); + AppEngineConfigurationUtil.createConfigurationFile( + project, new Path("app.yaml"), stream, true, null); + + verify(refreshHandler, atLeastOnce()).accept(anyObject(), anyObject()); + Object[] children = fixture.getChildren(project); + assertNotNull(children); + assertEquals(1, children.length); + assertTrue(children[0] instanceof AppEngineProjectElement); + AppEngineProjectElement projectElement = (AppEngineProjectElement) children[0]; + children = fixture.getChildren(projectElement); + assertNotNull(children); + assertEquals(0, children.length); + + IFile cronYaml = + AppEngineConfigurationUtil.createConfigurationFile( + project, new Path("cron.yaml"), ByteSource.empty().openStream(), true, null); + verify(refreshHandler, atLeastOnce()).accept(anyObject(), anyObject()); + children = fixture.getChildren(project); + assertNotNull(children); + assertEquals(1, children.length); + assertTrue(children[0] == projectElement); + children = fixture.getChildren(projectElement); + assertNotNull(children); + assertEquals(1, children.length); + assertThat(children, hasItemInArray(instanceOf(CronDescriptor.class))); + + AppEngineConfigurationUtil.createConfigurationFile( + project, new Path("index.yaml"), ByteSource.empty().openStream(), true, null); + verify(refreshHandler, atLeastOnce()).accept(anyObject(), anyObject()); + children = fixture.getChildren(project); + assertNotNull(children); + assertEquals(1, children.length); + assertTrue(children[0] == projectElement); + children = fixture.getChildren(projectElement); + assertNotNull(children); + assertEquals(2, children.length); + assertThat(children, hasItemInArray(instanceOf(CronDescriptor.class))); + assertThat(children, hasItemInArray(instanceOf(DatastoreIndexesDescriptor.class))); + + cronYaml.delete(true, null); + verify(refreshHandler, atLeastOnce()).accept(anyObject(), anyObject()); + children = fixture.getChildren(project); + assertNotNull(children); + assertEquals(1, children.length); + assertTrue(children[0] == projectElement); + children = fixture.getChildren(projectElement); + assertNotNull(children); + assertEquals(1, children.length); + assertThat(children, hasItemInArray(instanceOf(DatastoreIndexesDescriptor.class))); + } + + /** + * Test that a newly-created {@code appengine-web.xml} replaces the {@code app.yaml} for the + * {@link AppEngineProjectElement}. + */ + @Test + public void testDynamicChanges_appEngineWebXml_appYaml() throws CoreException { + projectCreator.withFacets(AppEngineStandardFacet.JRE7, WebFacetUtils.WEB_25); + IProject project = projectCreator.getProject(); + + StructuredViewer viewer = mock(StructuredViewer.class); + fixture.inputChanged(viewer, null, null); // installs resource-changed listener + + IFile appEngineWebXml = + AppEngineConfigurationUtil.findConfigurationFile(project, new Path("appengine-web.xml")); + assertTrue(appEngineWebXml != null && appEngineWebXml.exists()); + Object[] children = fixture.getChildren(project); + assertNotNull(children); + assertEquals(1, children.length); + assertTrue(children[0] instanceof AppEngineProjectElement); + final AppEngineProjectElement projectElement = (AppEngineProjectElement) children[0]; + assertEquals(appEngineWebXml, projectElement.getDescriptorFile()); + + // appengine-web.xml should still win + ByteArrayInputStream stream = + new ByteArrayInputStream("runtime: java\n".getBytes(StandardCharsets.UTF_8)); + IFile appYaml = + AppEngineConfigurationUtil.createConfigurationFile( + project, new Path("app.yaml"), stream, true, null); + verifyZeroInteractions(refreshHandler); // appengine-web.xml still wins + children = fixture.getChildren(project); + assertNotNull(children); + assertEquals(1, children.length); + assertSame("the project element instance shouldn't change", projectElement, children[0]); + assertEquals( + "appengine.web.xml should still win", appEngineWebXml, projectElement.getDescriptorFile()); + + // app.yaml should now win + appEngineWebXml.delete(true, null); + verify(refreshHandler, atLeastOnce()).accept(anyObject(), anyObject()); + children = fixture.getChildren(project); + assertNotNull(children); + assertEquals(1, children.length); + assertSame("the project element instance shouldn't change", projectElement, children[0]); + assertEquals("app.yaml should win", appYaml, projectElement.getDescriptorFile()); + + // appengine-web.xml should win again + appEngineWebXml = ConfigurationFileUtils.createAppEngineWebXml(project, null); + verify(refreshHandler, atLeastOnce()).accept(anyObject(), anyObject()); + children = fixture.getChildren(project); + assertNotNull(children); + assertEquals(1, children.length); + assertSame("the project element instance shouldn't change", projectElement, children[0]); + assertEquals("back to appengine-web.xml", appEngineWebXml, projectElement.getDescriptorFile()); + } + @Test public void testGetParent() { projectCreator.withFacets(AppEngineStandardFacet.JRE7, WebFacetUtils.WEB_25); @@ -301,7 +424,7 @@ public void testGetParent() { // must populate the model via the AppEngineContentProvider Object[] children = fixture.getChildren(project); assertEquals(1, children.length); - AppEngineStandardProjectElement projectElement = (AppEngineStandardProjectElement) children[0]; + AppEngineProjectElement projectElement = (AppEngineProjectElement) children[0]; children = fixture.getChildren(projectElement); assertEquals(1, children.length); TaskQueuesDescriptor queueDescriptor = (TaskQueuesDescriptor) children[0]; diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineLabelProviderTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineLabelProviderTest.java index 092e07c03c..da9eae12d7 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineLabelProviderTest.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineLabelProviderTest.java @@ -19,12 +19,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.doReturn; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.google.cloud.tools.appengine.AppEngineDescriptor; -import com.google.cloud.tools.appengine.api.AppEngineException; +import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineProjectElement; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.CronDescriptor; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.DatastoreIndexesDescriptor; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.DenialOfServiceDescriptor; @@ -32,12 +32,14 @@ import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.TaskQueuesDescriptor; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ResourceManager; import org.junit.Test; public class AppEngineLabelProviderTest { - private final AppEngineLabelProvider fixture = - new AppEngineLabelProvider(mock(ResourceManager.class)); + private final ResourceManager resourceManager = mock(ResourceManager.class); + private final AppEngineLabelProvider fixture = new AppEngineLabelProvider(resourceManager); + private final AppEngineProjectElement programElement = mock(AppEngineProjectElement.class); @Test public void testProjectText_noAppEngineWebXml() { @@ -45,153 +47,203 @@ public void testProjectText_noAppEngineWebXml() { // descriptor, which is generated from getVersionTuple(). This test ensures that // we don't generate a text string when no appengine-web.xml is found. IProject project = mock(IProject.class); - assertNull(AppEngineLabelProvider.getAppEngineStandardProjectText(project)); + assertNull(AppEngineLabelProvider.getAppEngineProjectText(project)); } @Test - public void testAppEngineVersionTuple_null() throws AppEngineException { - String result = AppEngineLabelProvider.getVersionTuple(null); + public void testAppEngineVersionTuple_nulls() { + String result = AppEngineLabelProvider.getVersionTuple(programElement); assertNotNull(result); assertEquals(0, result.length()); } @Test - public void testAppEngineVersionTuple_noData() throws AppEngineException { - AppEngineDescriptor descriptor = mock(AppEngineDescriptor.class); - doReturn(null).when(descriptor).getProjectId(); - doReturn(null).when(descriptor).getServiceId(); - doReturn(null).when(descriptor).getProjectVersion(); - - String result = AppEngineLabelProvider.getVersionTuple(descriptor); - assertNotNull(result); - assertEquals(0, result.length()); - } - - @Test - public void testAppEngineVersionTuple_project() throws AppEngineException { - AppEngineDescriptor descriptor = mock(AppEngineDescriptor.class); - doReturn("project").when(descriptor).getProjectId(); - doReturn(null).when(descriptor).getServiceId(); - doReturn(null).when(descriptor).getProjectVersion(); - - String result = AppEngineLabelProvider.getVersionTuple(descriptor); + public void testAppEngineVersionTuple_project() { + when(programElement.getProjectId()).thenReturn("project"); + String result = AppEngineLabelProvider.getVersionTuple(programElement); assertEquals("project", result); } @Test - public void testAppEngineVersionTuple_service() throws AppEngineException { - AppEngineDescriptor descriptor = mock(AppEngineDescriptor.class); - doReturn(null).when(descriptor).getProjectId(); - doReturn("service").when(descriptor).getServiceId(); - doReturn(null).when(descriptor).getProjectVersion(); - - String result = AppEngineLabelProvider.getVersionTuple(descriptor); - assertEquals("service", result); + public void testAppEngineVersionTuple_version() { + when(programElement.getProjectVersion()).thenReturn("version"); + String result = AppEngineLabelProvider.getVersionTuple(programElement); + assertEquals("version", result); } @Test - public void testAppEngineVersionTuple_version() throws AppEngineException { - AppEngineDescriptor descriptor = mock(AppEngineDescriptor.class); - doReturn(null).when(descriptor).getProjectId(); - doReturn(null).when(descriptor).getServiceId(); - doReturn("version").when(descriptor).getProjectVersion(); - - String result = AppEngineLabelProvider.getVersionTuple(descriptor); - assertEquals("version", result); + public void testAppEngineVersionTuple_service() { + when(programElement.getServiceId()).thenReturn("service"); + String result = AppEngineLabelProvider.getVersionTuple(programElement); + assertEquals("service", result); } @Test - public void testAppEngineVersionTuple_projectVersion() throws AppEngineException { - AppEngineDescriptor descriptor = mock(AppEngineDescriptor.class); - doReturn("project").when(descriptor).getProjectId(); - doReturn(null).when(descriptor).getServiceId(); - doReturn("version").when(descriptor).getProjectVersion(); - - String result = AppEngineLabelProvider.getVersionTuple(descriptor); + public void testAppEngineVersionTuple_project_version() { + when(programElement.getProjectId()).thenReturn("project"); + when(programElement.getProjectVersion()).thenReturn("version"); + String result = AppEngineLabelProvider.getVersionTuple(programElement); assertEquals("project:version", result); } @Test - public void testAppEngineVersionTuple_projectService() throws AppEngineException { - AppEngineDescriptor descriptor = mock(AppEngineDescriptor.class); - doReturn("project").when(descriptor).getProjectId(); - doReturn("service").when(descriptor).getServiceId(); - doReturn(null).when(descriptor).getProjectVersion(); - - String result = AppEngineLabelProvider.getVersionTuple(descriptor); + public void testAppEngineVersionTuple_project_service() { + when(programElement.getProjectId()).thenReturn("project"); + when(programElement.getServiceId()).thenReturn("service"); + String result = AppEngineLabelProvider.getVersionTuple(programElement); assertEquals("project:service", result); } @Test - public void testAppEngineVersionTuple_versionService() throws AppEngineException { - AppEngineDescriptor descriptor = mock(AppEngineDescriptor.class); - doReturn(null).when(descriptor).getProjectId(); - doReturn("service").when(descriptor).getServiceId(); - doReturn("version").when(descriptor).getProjectVersion(); - - String result = AppEngineLabelProvider.getVersionTuple(descriptor); + public void testAppEngineVersionTuple_version_service() { + when(programElement.getProjectVersion()).thenReturn("version"); + when(programElement.getServiceId()).thenReturn("service"); + String result = AppEngineLabelProvider.getVersionTuple(programElement); assertEquals("service:version", result); } @Test - public void testAppEngineVersionTuple_projectVersionService() - throws AppEngineException { - AppEngineDescriptor descriptor = mock(AppEngineDescriptor.class); - doReturn("project").when(descriptor).getProjectId(); - doReturn("service").when(descriptor).getServiceId(); - doReturn("version").when(descriptor).getProjectVersion(); - - String result = AppEngineLabelProvider.getVersionTuple(descriptor); + public void testAppEngineVersionTuple_project_version_service() { + when(programElement.getProjectId()).thenReturn("project"); + when(programElement.getProjectVersion()).thenReturn("version"); + when(programElement.getServiceId()).thenReturn("service"); + String result = AppEngineLabelProvider.getVersionTuple(programElement); assertEquals("project:service:version", result); } @Test - public void testCronDescriptor() { + public void testGetText_cronDescriptor_xml() { IFile file = mock(IFile.class); when(file.getName()).thenReturn("cron.xml"); when(file.exists()).thenReturn(true); when(file.getProject()).thenReturn(mock(IProject.class)); CronDescriptor element = new CronDescriptor(file); - assertEquals("Scheduled Tasks", fixture.getText(element)); + assertEquals("Scheduled Tasks - cron.xml", fixture.getText(element)); } @Test - public void testDatastoreIndexesDescriptor() { + public void testGetText_datastoreIndexesDescriptor_xml() { IFile file = mock(IFile.class); when(file.getName()).thenReturn("datastore-indexes.xml"); when(file.exists()).thenReturn(true); when(file.getProject()).thenReturn(mock(IProject.class)); DatastoreIndexesDescriptor element = new DatastoreIndexesDescriptor(file); - assertEquals("Datastore Indexes", fixture.getText(element)); + assertEquals("Datastore Indexes - datastore-indexes.xml", fixture.getText(element)); } @Test - public void testDenialOfServiceDescriptor() { + public void testGetText_denialOfServiceDescriptor_xml() { IFile file = mock(IFile.class); when(file.getName()).thenReturn("dos.xml"); when(file.exists()).thenReturn(true); when(file.getProject()).thenReturn(mock(IProject.class)); DenialOfServiceDescriptor element = new DenialOfServiceDescriptor(file); - assertEquals("Denial of Service Protection", fixture.getText(element)); + assertEquals("Denial of Service Protection - dos.xml", fixture.getText(element)); } @Test - public void testDispatchRoutingDescriptor() { + public void testGetText_dispatchRoutingDescriptor_xml() { IFile file = mock(IFile.class); when(file.getName()).thenReturn("dispatch.xml"); when(file.exists()).thenReturn(true); when(file.getProject()).thenReturn(mock(IProject.class)); DispatchRoutingDescriptor element = new DispatchRoutingDescriptor(file); - assertEquals("Dispatch Routing Rules", fixture.getText(element)); + assertEquals("Dispatch Routing Rules - dispatch.xml", fixture.getText(element)); } @Test - public void testTaskQueuesDescriptor() { + public void testGetText_taskQueuesDescriptor_xml() { IFile file = mock(IFile.class); when(file.getName()).thenReturn("queue.xml"); when(file.exists()).thenReturn(true); when(file.getProject()).thenReturn(mock(IProject.class)); TaskQueuesDescriptor element = new TaskQueuesDescriptor(file); - assertEquals("Task Queue Definitions", fixture.getText(element)); + assertEquals("Task Queue Definitions - queue.xml", fixture.getText(element)); + } + + @Test + public void testGetText_cronDescriptor_yaml() { + IFile file = mock(IFile.class); + when(file.getName()).thenReturn("cron.yaml"); + when(file.exists()).thenReturn(true); + when(file.getProject()).thenReturn(mock(IProject.class)); + CronDescriptor element = new CronDescriptor(file); + assertEquals("Scheduled Tasks - cron.yaml", fixture.getText(element)); + } + + @Test + public void testGetText_datastoreIndexesDescriptor_yaml() { + IFile file = mock(IFile.class); + when(file.getName()).thenReturn("index.yaml"); + when(file.exists()).thenReturn(true); + when(file.getProject()).thenReturn(mock(IProject.class)); + DatastoreIndexesDescriptor element = new DatastoreIndexesDescriptor(file); + assertEquals("Datastore Indexes - index.yaml", fixture.getText(element)); + } + + @Test + public void testGetText_denialOfServiceDescriptor_yaml() { + IFile file = mock(IFile.class); + when(file.getName()).thenReturn("dos.yaml"); + when(file.exists()).thenReturn(true); + when(file.getProject()).thenReturn(mock(IProject.class)); + DenialOfServiceDescriptor element = new DenialOfServiceDescriptor(file); + assertEquals("Denial of Service Protection - dos.yaml", fixture.getText(element)); + } + + @Test + public void testGetText_dispatchRoutingDescriptor_yaml() { + IFile file = mock(IFile.class); + when(file.getName()).thenReturn("dispatch.yaml"); + when(file.exists()).thenReturn(true); + when(file.getProject()).thenReturn(mock(IProject.class)); + DispatchRoutingDescriptor element = new DispatchRoutingDescriptor(file); + assertEquals("Dispatch Routing Rules - dispatch.yaml", fixture.getText(element)); + } + + @Test + public void testGetText_taskQueuesDescriptor_yaml() { + IFile file = mock(IFile.class); + when(file.getName()).thenReturn("queue.yaml"); + when(file.exists()).thenReturn(true); + when(file.getProject()).thenReturn(mock(IProject.class)); + TaskQueuesDescriptor element = new TaskQueuesDescriptor(file); + assertEquals("Task Queue Definitions - queue.yaml", fixture.getText(element)); + } + + @Test + public void testGetImage_appEngineProjectElement() { + fixture.getImage(mock(AppEngineProjectElement.class)); + verify(resourceManager).create(any(ImageDescriptor.class)); + } + + @Test + public void testGetImage_cronDescriptor() { + fixture.getImage(mock(CronDescriptor.class)); + verify(resourceManager).create(any(ImageDescriptor.class)); + } + + @Test + public void testGetImage_datastoreIndexesDescriptor() { + fixture.getImage(mock(DatastoreIndexesDescriptor.class)); + verify(resourceManager).create(any(ImageDescriptor.class)); + } + + @Test + public void testGetImage_denialOfServiceDescriptor() { + fixture.getImage(mock(DenialOfServiceDescriptor.class)); + verify(resourceManager).create(any(ImageDescriptor.class)); + } + + @Test + public void testGetImage_dispatchRoutingDescriptor() { + fixture.getImage(mock(DispatchRoutingDescriptor.class)); + verify(resourceManager).create(any(ImageDescriptor.class)); + } + + @Test + public void testGetImage_taskQueueDescriptor() { + fixture.getImage(mock(TaskQueuesDescriptor.class)); + verify(resourceManager).create(any(ImageDescriptor.class)); } } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/PluginXmlTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/PluginXmlTest.java index 7bf5a12400..b897179704 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/PluginXmlTest.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/PluginXmlTest.java @@ -19,8 +19,10 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineFlexJarFacet; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineFlexWarFacet; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; -import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineStandardProjectElement; +import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineProjectElement; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.CronDescriptor; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.DatastoreIndexesDescriptor; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.DenialOfServiceDescriptor; @@ -94,6 +96,37 @@ public void testNavigatorContentTriggerExpression_appEngineStandardJavaProject() triggerExpression.evaluate(new EvaluationContext(null, projectCreator.getProject()))); } + @Test + public void testNavigatorContentTriggerExpression_appEngineFlexibleWarJavaProject() + throws CoreException { + Element triggerPoints = + findElement( + "//plugin/extension[@point='org.eclipse.ui.navigator.navigatorContent']" + + "/navigatorContent[@id='com.google.cloud.tools.eclipse.appengine.navigator']" + + "/triggerPoints/*"); + Expression triggerExpression = checkExpression(triggerPoints); + projectCreator.withFacets( + AppEngineFlexWarFacet.FACET_VERSION, JavaFacet.VERSION_1_8, WebFacetUtils.WEB_31); + assertEquals( + EvaluationResult.TRUE, + triggerExpression.evaluate(new EvaluationContext(null, projectCreator.getProject()))); + } + + @Test + public void testNavigatorContentTriggerExpression_appEngineFlexibleJarJavaProject() + throws CoreException { + Element triggerPoints = + findElement( + "//plugin/extension[@point='org.eclipse.ui.navigator.navigatorContent']" + + "/navigatorContent[@id='com.google.cloud.tools.eclipse.appengine.navigator']" + + "/triggerPoints/*"); + Expression triggerExpression = checkExpression(triggerPoints); + projectCreator.withFacets(AppEngineFlexJarFacet.FACET_VERSION, JavaFacet.VERSION_1_8); + assertEquals( + EvaluationResult.TRUE, + triggerExpression.evaluate(new EvaluationContext(null, projectCreator.getProject()))); + } + @Test public void testNavigatorContentActionProvider() throws CoreException { Element actionProvider = @@ -110,7 +143,7 @@ public void testNavigatorContentActionProvider() throws CoreException { assertEquals( EvaluationResult.TRUE, enablementExpression.evaluate( - new EvaluationContext(null, mock(AppEngineStandardProjectElement.class)))); + new EvaluationContext(null, mock(AppEngineProjectElement.class)))); assertEquals( EvaluationResult.TRUE, enablementExpression.evaluate(new EvaluationContext(null, mock(CronDescriptor.class)))); diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineProjectElementTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineProjectElementTest.java new file mode 100644 index 0000000000..87dc7ac91e --- /dev/null +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineProjectElementTest.java @@ -0,0 +1,195 @@ +/* + * Copyright 2018 Google LLC + * + * 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.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.google.cloud.tools.appengine.api.AppEngineException; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineFlexWarFacet; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; +import com.google.cloud.tools.eclipse.test.util.project.TestProjectCreator; +import java.util.Collections; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; +import org.eclipse.jst.common.project.facet.core.JavaFacet; +import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils; +import org.junit.Rule; +import org.junit.Test; + +public class AppEngineProjectElementTest { + @Rule public TestProjectCreator projectCreator = new TestProjectCreator(); + + @Test + public void testCreation_appEngineStandardJava7() throws AppEngineException { + projectCreator.withFacets( + AppEngineStandardFacet.JRE7, WebFacetUtils.WEB_25, JavaFacet.VERSION_1_7); + IProject project = projectCreator.getProject(); + + AppEngineProjectElement projectElement = AppEngineProjectElement.create(project); + assertNotNull(projectElement); + assertNotNull(projectElement.getDescriptorFile()); + assertEquals("appengine-web.xml", projectElement.getDescriptorFile().getName()); + } + + @Test + public void testCreation_appEngineFlexibleWar() throws AppEngineException { + projectCreator.withFacets( + AppEngineFlexWarFacet.FACET_VERSION, WebFacetUtils.WEB_31, JavaFacet.VERSION_1_8); + IProject project = projectCreator.getProject(); + + AppEngineProjectElement projectElement = AppEngineProjectElement.create(project); + assertNotNull(projectElement); + assertNotNull(projectElement.getDescriptorFile()); + assertEquals("app.yaml", projectElement.getDescriptorFile().getName()); + } + + @Test + public void testEnvironmentRuntime_xml_noRuntime() throws CoreException, AppEngineException { + IProject project = projectCreator.getProject(); + String contents = ""; + AppEngineConfigurationUtil.createConfigurationFile( + project, new Path("appengine-web.xml"), contents, true, null); + + AppEngineProjectElement projectElement = AppEngineProjectElement.create(project); + assertNotNull(projectElement); + assertEquals("standard", projectElement.getEnvironmentType()); + assertEquals("java7", projectElement.getRuntime()); + } + + @Test + public void testEnvironmentRuntime_xml_java8Runtime() throws CoreException, AppEngineException { + IProject project = projectCreator.getProject(); + String contents = + "" + + "java8" + + ""; + AppEngineConfigurationUtil.createConfigurationFile( + project, new Path("appengine-web.xml"), contents, true, null); + + AppEngineProjectElement projectElement = AppEngineProjectElement.create(project); + assertNotNull(projectElement); + assertEquals("standard", projectElement.getEnvironmentType()); + assertEquals("java8", projectElement.getRuntime()); + } + + @Test + public void testEnvironmentRuntime_yaml_python27() throws CoreException, AppEngineException { + IProject project = projectCreator.getProject(); + String contents = "runtime: python27"; + AppEngineConfigurationUtil.createConfigurationFile( + project, new Path("app.yaml"), contents, true, null); + + AppEngineProjectElement projectElement = AppEngineProjectElement.create(project); + assertNotNull(projectElement); + assertEquals("standard", projectElement.getEnvironmentType()); + assertEquals("python27", projectElement.getRuntime()); + } + + @Test + public void testEnvironmentRuntime_yaml_python27_flex() throws CoreException, AppEngineException { + IProject project = projectCreator.getProject(); + String contents = "runtime: python27\nenv: flex"; + AppEngineConfigurationUtil.createConfigurationFile( + project, new Path("app.yaml"), contents, true, null); + + AppEngineProjectElement projectElement = AppEngineProjectElement.create(project); + assertNotNull(projectElement); + assertEquals("flex", projectElement.getEnvironmentType()); + assertEquals("python27", projectElement.getRuntime()); + } + + @Test + public void testGetAdapter() throws AppEngineException { + projectCreator.withFacets( + AppEngineStandardFacet.JRE7, + WebFacetUtils.WEB_25, + JavaFacet.VERSION_1_7); + IProject project = projectCreator.getProject(); + + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(project); + assertNotNull(projectElement); + assertNotNull(projectElement.getAdapter(IFile.class)); + } + + @Test + public void testHasLayoutChanged_normalFile() { + IFile file = mock(IFile.class); + when(file.getProjectRelativePath()).thenReturn(new Path("foo")); + assertFalse(AppEngineProjectElement.hasLayoutChanged(Collections.singleton(file))); + } + + @Test + public void testHasLayoutChanged_otherComponentsFile() { + IFile file = mock(IFile.class); + // not in .settings + when(file.getProjectRelativePath()).thenReturn(new Path("org.eclipse.wst.common.component")); + assertFalse(AppEngineProjectElement.hasLayoutChanged(Collections.singleton(file))); + } + + @Test + public void testHasLayoutChanged_settingsFile() { + IFile file = mock(IFile.class); + when(file.getProjectRelativePath()).thenReturn(new Path(".settings/foo")); + assertFalse(AppEngineProjectElement.hasLayoutChanged(Collections.singleton(file))); + } + + @Test + public void testHasLayoutChanged_wtpComponentsFile() { + IFile file = mock(IFile.class); + when(file.getProjectRelativePath()) + .thenReturn(new Path(".settings/org.eclipse.wst.common.component")); + assertTrue(AppEngineProjectElement.hasLayoutChanged(Collections.singleton(file))); + } + + @Test + public void testHasLayoutChanged_wtpFacetsFile() { + IFile file = mock(IFile.class); + when(file.getProjectRelativePath()) + .thenReturn(new Path(".settings/org.eclipse.wst.common.project.facet.core.xml")); + assertTrue(AppEngineProjectElement.hasLayoutChanged(Collections.singleton(file))); + } + + @Test + public void testHasAppEngineDescriptor_normalFile() { + IFile file = mock(IFile.class); + when(file.getName()).thenReturn("org.eclipse.wst.common.project.facet.core.xml"); + assertFalse(AppEngineProjectElement.hasAppEngineDescriptor(Collections.singleton(file))); + } + + @Test + public void testHasAppEngineDescriptor_appEngineWebXml() { + IFile file = mock(IFile.class); + when(file.getName()).thenReturn("appengine-web.xml"); + assertTrue(AppEngineProjectElement.hasAppEngineDescriptor(Collections.singleton(file))); + } + + @Test + public void testHasAppEngineDescriptor_appYaml() { + IFile file = mock(IFile.class); + when(file.getName()).thenReturn("app.yaml"); + assertTrue(AppEngineProjectElement.hasAppEngineDescriptor(Collections.singleton(file))); + } +} diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineStandardProjectElementTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineStandardProjectElementTest.java deleted file mode 100644 index fc5a7f810b..0000000000 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineStandardProjectElementTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2018 Google LLC - * - * 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.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.google.cloud.tools.appengine.api.AppEngineException; -import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; -import com.google.cloud.tools.eclipse.test.util.project.TestProjectCreator; -import java.util.Collections; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.Path; -import org.eclipse.jst.common.project.facet.core.JavaFacet; -import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils; -import org.junit.Rule; -import org.junit.Test; - -public class AppEngineStandardProjectElementTest { - @Rule public TestProjectCreator projectCreator = new TestProjectCreator(); - - @Test - public void testGetAdapter() throws AppEngineException { - projectCreator.withFacets( - AppEngineStandardFacet.JRE7, - WebFacetUtils.WEB_25, - JavaFacet.VERSION_1_7); - IProject project = projectCreator.getProject(); - - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(project); - assertNotNull(projectElement); - assertNotNull(projectElement.getAdapter(IFile.class)); - } - - @Test - public void testHasLayoutChanged_normalFile() { - IFile file = mock(IFile.class); - when(file.getProjectRelativePath()).thenReturn(new Path("foo")); - assertFalse(AppEngineStandardProjectElement.hasLayoutChanged(Collections.singleton(file))); - } - - @Test - public void testHasLayoutChanged_otherComponentsFile() { - IFile file = mock(IFile.class); - // not in .settings - when(file.getProjectRelativePath()).thenReturn(new Path("org.eclipse.wst.common.component")); - assertFalse(AppEngineStandardProjectElement.hasLayoutChanged(Collections.singleton(file))); - } - - @Test - public void testHasLayoutChanged_settingsFile() { - IFile file = mock(IFile.class); - when(file.getProjectRelativePath()).thenReturn(new Path(".settings/foo")); - assertFalse(AppEngineStandardProjectElement.hasLayoutChanged(Collections.singleton(file))); - } - - @Test - public void testHasLayoutChanged_wtpComponentsFile() { - IFile file = mock(IFile.class); - when(file.getProjectRelativePath()) - .thenReturn(new Path(".settings/org.eclipse.wst.common.component")); - assertTrue(AppEngineStandardProjectElement.hasLayoutChanged(Collections.singleton(file))); - } - - @Test - public void testHasLayoutChanged_wtpFacetsFile() { - IFile file = mock(IFile.class); - when(file.getProjectRelativePath()) - .thenReturn(new Path(".settings/org.eclipse.wst.common.project.facet.core.xml")); - assertTrue(AppEngineStandardProjectElement.hasLayoutChanged(Collections.singleton(file))); - } -} diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/ModelRefreshTests.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/ModelRefreshTests.java index 729ee6efd9..d52f728746 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/ModelRefreshTests.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/ModelRefreshTests.java @@ -57,7 +57,7 @@ import org.junit.Rule; import org.junit.Test; -/** Test creation of AppEngineStandardProjectElement and its sub-elements. */ +/** Test creation of AppEngineProjectElement and its sub-elements. */ public class ModelRefreshTests { @Rule public TestProjectCreator projectCreator = @@ -69,7 +69,7 @@ public class ModelRefreshTests { /** Verify that the content block is configured for initial configuration files. */ @Test - public void testAppEngineStandardProjectElementCreate_initial() throws AppEngineException { + public void testAppEngineProjectElementCreate_initial() throws AppEngineException { IProject project = projectCreator.getProject(); IFile cronXml = ConfigurationFileUtils.createEmptyCronXml(project); IFile datastoreIndexesXml = @@ -78,8 +78,8 @@ public void testAppEngineStandardProjectElementCreate_initial() throws AppEngine IFile dosXml = ConfigurationFileUtils.createEmptyDosXml(project); IFile queueXml = ConfigurationFileUtils.createEmptyQueueXml(project); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(project); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(project); AppEngineResourceElement[] subElements = projectElement.getConfigurations(); assertNotNull(subElements); assertEquals(5, subElements.length); @@ -103,10 +103,10 @@ public void testAppEngineStandardProjectElementCreate_initial() throws AppEngine /** Verify that the content block is progressively updated as configuration files are added. */ @Test - public void testAppEngineStandardProjectElementCreate_staggered() throws AppEngineException { + public void testAppEngineProjectElementCreate_staggered() throws AppEngineException { IProject project = projectCreator.getProject(); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(project); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(project); AppEngineResourceElement[] subElements = projectElement.getConfigurations(); assertNotNull(subElements); assertEquals(0, subElements.length); @@ -181,8 +181,8 @@ public void testChangeToDefaultPreservesConfigurationElements() throws AppEngine ConfigurationFileUtils.createEmptyDispatchXml(project); ConfigurationFileUtils.createEmptyDosXml(project); ConfigurationFileUtils.createEmptyQueueXml(project); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(project); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(project); final AppEngineResourceElement[] subElements = projectElement.getConfigurations(); assertEquals(5, subElements.length); assertThat(subElements, hasItemInArray(instanceOf(CronDescriptor.class))); @@ -213,8 +213,8 @@ public void testChangeToNonDefaultDiscardsConfigurationElements() throws AppEngi ConfigurationFileUtils.createEmptyDispatchXml(project); ConfigurationFileUtils.createEmptyDosXml(project); ConfigurationFileUtils.createEmptyQueueXml(project); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(project); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(project); final AppEngineResourceElement[] subElements = projectElement.getConfigurations(); assertEquals(5, subElements.length); assertThat(subElements, hasItemInArray(instanceOf(CronDescriptor.class))); @@ -245,8 +245,8 @@ public void testChildElementPreservedOnChange() throws AppEngineException { files.add(ConfigurationFileUtils.createEmptyDosXml(project)); files.add(ConfigurationFileUtils.createEmptyQueueXml(project)); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(project); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(project); files.add(projectElement.getDescriptorFile()); final AppEngineResourceElement[] subElements = projectElement.getConfigurations(); @@ -268,8 +268,8 @@ public void testNonDefaultServiceIgnoresNewFiles() throws AppEngineException { IProject project = projectCreator.getProject(); ConfigurationFileUtils.createAppEngineWebXml(project, "non-default"); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(project); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(project); AppEngineResourceElement[] subElements = projectElement.getConfigurations(); assertEquals(0, subElements.length); @@ -289,8 +289,8 @@ public void testRejigDeploymentAssembly() throws AppEngineException, CoreExcepti IProject project = projectCreator.getProject(); // verify the new files are not picked up yet IFile oldCronXml = ConfigurationFileUtils.createEmptyCronXml(project); - AppEngineStandardProjectElement projectElement = - AppEngineStandardProjectElement.create(project); + AppEngineProjectElement projectElement = + AppEngineProjectElement.create(project); final AppEngineResourceElement[] oldElements = projectElement.getConfigurations(); assertEquals(1, oldElements.length); assertThat(oldElements, hasItemInArray(instanceOf(CronDescriptor.class))); diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/plugin.xml b/plugins/com.google.cloud.tools.eclipse.appengine.facets/plugin.xml index 37a1761dda..2235c10c03 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/plugin.xml +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/plugin.xml @@ -312,10 +312,20 @@ - - + + + + + + + + @@ -332,7 +342,7 @@ value="com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineResourceElement"> + value="com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineProjectElement"> diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineConfigurationUtil.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineConfigurationUtil.java new file mode 100644 index 0000000000..9f6848d339 --- /dev/null +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineConfigurationUtil.java @@ -0,0 +1,114 @@ +/* + * Copyright 2018 Google LLC + * + * 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.google.cloud.tools.eclipse.appengine.facets; + +import com.google.cloud.tools.eclipse.util.io.ResourceUtils; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; + +/** + * Utility class for resolving App Engine configuration files in a project. The goal of this class + * is to insulate callers from having to know how and when configuration files are placed within a + * project. For example, Java projects for the flexible environment typically place their YAML + * configuration files in {@code src/main/appengine} whereas Java projects for the standard + * environment place their XML configuration files within the {@code WEB-INF} directory. + * + * @see WebProjectUtil + */ +public class AppEngineConfigurationUtil { + /** A well-known location for App Engine configuration files. */ + private static final IPath DEFAULT_CONFIGURATION_FILE_LOCATION = new Path("src/main/appengine"); + + /** + * Create an App Engine configuration file in the appropriate location for the project. + * + * @param project the hosting project + * @param relativePath the path of the file relative to the configuration location + * @param contents the content for the file + * @param overwrite if {@code true} then overwrite the file if it exists + */ + public static IFile createConfigurationFile( + IProject project, + IPath relativePath, + String contents, + boolean overwrite, + IProgressMonitor monitor) + throws CoreException { + InputStream bytes = new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8)); + return createConfigurationFile(project, relativePath, bytes, overwrite, monitor); + } + + /** + * Create an App Engine configuration file in the appropriate location for the project. + * + * @param project the hosting project + * @param relativePath the path of the file relative to the configuration location + * @param contents the content for the file + * @param overwrite if {@code true} then overwrite the file if it exists + */ + public static IFile createConfigurationFile( + IProject project, + IPath relativePath, + InputStream contents, + boolean overwrite, + IProgressMonitor monitor) + throws CoreException { + IFolder appengineFolder = project.getFolder(DEFAULT_CONFIGURATION_FILE_LOCATION); + if (appengineFolder != null && appengineFolder.exists()) { + IFile destination = appengineFolder.getFile(relativePath); + if (!destination.exists()) { + IContainer parent = destination.getParent(); + ResourceUtils.createFolders(parent, monitor); + destination.create(contents, true, monitor); + } else if (overwrite) { + destination.setContents(contents, IResource.FORCE, monitor); + } + return destination; + } + return WebProjectUtil.createFileInWebInf(project, relativePath, contents, overwrite, monitor); + } + + /** + * Attempt to resolve the given file within the project's {@code WEB-INF}. Note that this method + * may return a file that is in a build location (e.g., {@code + * target/m2e-wtp/web-resources/WEB-INF}) which may be frequently removed or regenerated. + * + * @return the file location or {@code null} if not found + */ + public static IFile findConfigurationFile(IProject project, IPath relativePath) { + IFolder appengineFolder = project.getFolder(DEFAULT_CONFIGURATION_FILE_LOCATION); + if (appengineFolder != null && appengineFolder.exists()) { + IFile destination = appengineFolder.getFile(relativePath); + if (destination.exists()) { + return destination; + } + } + return WebProjectUtil.findInWebInf(project, relativePath); + } + + private AppEngineConfigurationUtil() {} // not intended to be instantiated +} diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineStandardJre7ProjectFacetDetector.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineStandardJre7ProjectFacetDetector.java index 05236fa994..dec26b508f 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineStandardJre7ProjectFacetDetector.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/AppEngineStandardJre7ProjectFacetDetector.java @@ -57,7 +57,8 @@ public void detect(IFacetedProjectWorkingCopy workingCopy, IProgressMonitor moni } IFile appEngineWebXml = - WebProjectUtil.findInWebInf(workingCopy.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + workingCopy.getProject(), new Path("appengine-web.xml")); progress.worked(1); if (appEngineWebXml == null || !appEngineWebXml.exists()) { logger.fine("skipping " + projectName + ": cannot find appengine-web.xml"); diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/StandardFacetInstallDelegate.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/StandardFacetInstallDelegate.java index e15cf3fefc..d9ecaf6a30 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/StandardFacetInstallDelegate.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/StandardFacetInstallDelegate.java @@ -144,8 +144,12 @@ void createConfigFiles(IProject project, IProjectFacetVersion facetVersion, if (appEngineRuntime instanceof String) { parameters.put("runtime", (String) appEngineRuntime); } - createFileInWebInf(project, "appengine-web.xml", Templates.APPENGINE_WEB_XML_TEMPLATE, - parameters, progress.split(5)); + createAppEngineConfigurationFile( + project, + "appengine-web.xml", + Templates.APPENGINE_WEB_XML_TEMPLATE, + parameters, + progress.split(5)); } /** Creates a file in the WEB-INF folder if it doesn't exist. */ @@ -171,4 +175,34 @@ private void createFileInWebInf(IProject project, String filename, String templa progress.worked(4); targetFile.refreshLocal(IFile.DEPTH_ZERO, progress.split(1)); } + + /** Creates an App Engine configuration file in the appropriate folder, if it doesn't exist. */ + private void createAppEngineConfigurationFile( + IProject project, + String filename, + String templateName, + Map templateParameters, + IProgressMonitor monitor) + throws CoreException { + SubMonitor progress = SubMonitor.convert(monitor, 7); + + IFile targetFile = + AppEngineConfigurationUtil.findConfigurationFile(project, new Path(filename)); + if (targetFile != null && targetFile.exists()) { + return; + } + + // todo Templates should provide content as an InputStream + targetFile = + AppEngineConfigurationUtil.createConfigurationFile( + project, + new Path(filename), + new ByteArrayInputStream(new byte[0]), + false /* overwrite */, + progress.split(2)); + String fileLocation = targetFile.getLocation().toString(); + Templates.createFileContent(fileLocation, templateName, templateParameters); + progress.worked(4); + targetFile.refreshLocal(IFile.DEPTH_ZERO, progress.split(1)); + } } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineContentProvider.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineContentProvider.java index 0b8667eb03..a438d909f7 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineContentProvider.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineContentProvider.java @@ -17,16 +17,17 @@ package com.google.cloud.tools.eclipse.appengine.facets.ui.navigator; import com.google.cloud.tools.appengine.api.AppEngineException; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineFlexJarFacet; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineFlexWarFacet; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; +import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineProjectElement; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineResourceElement; -import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineStandardProjectElement; import com.google.cloud.tools.eclipse.util.io.ResourceUtils; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; import java.util.Collection; import java.util.HashSet; @@ -89,14 +90,17 @@ private static IProject getProject(Object inputElement) { return null; } - /** Return {@code true} if the project is an App Engine Standard project. */ - static boolean isStandard(IProject project) { + /** Return {@code true} if the project is an App Engine project. */ + static boolean isAppEngine(IProject project) { Preconditions.checkNotNull(project); try { IFacetedProject facetedProject = ProjectFacetsManager.create(project); - return facetedProject != null && AppEngineStandardFacet.hasFacet(facetedProject); + return facetedProject != null + && (AppEngineStandardFacet.hasFacet(facetedProject) + || AppEngineFlexWarFacet.hasFacet(facetedProject) + || AppEngineFlexJarFacet.hasFacet(facetedProject)); } catch (CoreException ex) { - logger.log(Level.INFO, "Project is not faceted", ex); + // Project is not faceted return false; } } @@ -106,26 +110,25 @@ static boolean isStandard(IProject project) { * * @throws AppEngineException if not an App Engine project */ - @VisibleForTesting - static AppEngineStandardProjectElement loadRepresentation(IProject project) + static AppEngineProjectElement loadRepresentation(IProject project) throws AppEngineException { Preconditions.checkNotNull(project); - if (!project.exists() || !isStandard(project)) { + if (!project.exists() || !isAppEngine(project)) { throw new AppEngineException("Not an App Engine project"); } - AppEngineStandardProjectElement appEngineProject = - AppEngineStandardProjectElement.create(project); + AppEngineProjectElement appEngineProject = + AppEngineProjectElement.create(project); return appEngineProject; } /** Cached representation of App Engine projects. */ - private final LoadingCache projectMapping = + private final LoadingCache projectMapping = CacheBuilder.newBuilder() .weakKeys() .build( - new CacheLoader() { + new CacheLoader() { @Override - public AppEngineStandardProjectElement load(IProject key) throws Exception { + public AppEngineProjectElement load(IProject key) throws Exception { return AppEngineContentProvider.loadRepresentation(key); } }); @@ -185,7 +188,7 @@ private void resourceChanged(IResourceChangeEvent event) { } Collection projectFiles = affected.get(project); // Do we have a model for this project? If so, then update it. - AppEngineStandardProjectElement projectElement = projectMapping.getIfPresent(project); + AppEngineProjectElement projectElement = projectMapping.getIfPresent(project); if (projectElement != null) { try { if (projectElement.resourcesChanged(projectFiles)) { @@ -204,8 +207,7 @@ private void resourceChanged(IResourceChangeEvent event) { projectMapping.invalidate(project); toBeRefreshed.add(project); } - } else if (Iterables.any( - projectFiles, file -> file != null && "appengine-web.xml".equals(file.getName()))) { + } else if (AppEngineProjectElement.hasAppEngineDescriptor(projectFiles)) { // We have no project model (wasn't an App Engine project previously) but it seems to // contain an App Engine descriptor. So trigger refresh of project. toBeRefreshed.add(project); @@ -239,8 +241,8 @@ public Object[] getElements(Object inputElement) { @Override public boolean hasChildren(Object element) { - if (element instanceof AppEngineStandardProjectElement) { - AppEngineStandardProjectElement projectElement = (AppEngineStandardProjectElement) element; + if (element instanceof AppEngineProjectElement) { + AppEngineProjectElement projectElement = (AppEngineProjectElement) element; return projectElement.getConfigurations().length > 0; } else if (element instanceof AppEngineResourceElement) { // none of our descriptor models have children @@ -250,19 +252,19 @@ public boolean hasChildren(Object element) { if (project == null) { return false; } - AppEngineStandardProjectElement webProject = projectMapping.getIfPresent(project); + AppEngineProjectElement webProject = projectMapping.getIfPresent(project); return webProject != null ? webProject.getConfigurations().length > 0 : true; } @Override public Object[] getChildren(Object parentElement) { - if (parentElement instanceof AppEngineStandardProjectElement) { - return ((AppEngineStandardProjectElement) parentElement).getConfigurations(); + if (parentElement instanceof AppEngineProjectElement) { + return ((AppEngineProjectElement) parentElement).getConfigurations(); } IProject project = getProject(parentElement); if (project != null) { try { - AppEngineStandardProjectElement projectElement = projectMapping.get(project); + AppEngineProjectElement projectElement = projectMapping.get(project); return projectElement == null ? EMPTY_ARRAY : new Object[] {projectElement}; } catch (ExecutionException ex) { // ignore: either not an App Engine project, or load failed due to a validation problem @@ -274,8 +276,8 @@ public Object[] getChildren(Object parentElement) { @Override public Object getParent(Object element) { - if (element instanceof AppEngineStandardProjectElement) { - return ((AppEngineStandardProjectElement) element).getProject(); + if (element instanceof AppEngineProjectElement) { + return ((AppEngineProjectElement) element).getProject(); } else if (element instanceof AppEngineResourceElement) { IProject project = ((AppEngineResourceElement) element).getProject(); return projectMapping.getIfPresent(project); diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineLabelProvider.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineLabelProvider.java index 6c6bf6cd79..0862f6c84c 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineLabelProvider.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/AppEngineLabelProvider.java @@ -16,22 +16,15 @@ package com.google.cloud.tools.eclipse.appengine.facets.ui.navigator; -import com.google.cloud.tools.appengine.AppEngineDescriptor; import com.google.cloud.tools.appengine.api.AppEngineException; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; +import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineProjectElement; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineResourceElement; -import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.AppEngineStandardProjectElement; import com.google.cloud.tools.eclipse.appengine.facets.ui.navigator.model.DatastoreIndexesDescriptor; import com.google.cloud.tools.eclipse.appengine.ui.AppEngineImages; import com.google.cloud.tools.eclipse.ui.util.images.SharedImages; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; -import java.io.IOException; -import java.io.InputStream; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.Path; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.resource.ResourceManager; @@ -39,7 +32,6 @@ import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.StyledString; import org.eclipse.swt.graphics.Image; -import org.xml.sax.SAXException; public class AppEngineLabelProvider extends LabelProvider implements IStyledLabelProvider { private final ResourceManager resources; @@ -61,10 +53,10 @@ public String getText(Object element) { @Override public StyledString getStyledText(Object element) { - if (element instanceof IProject && AppEngineContentProvider.isStandard((IProject) element)) { - return getAppEngineStandardProjectText((IProject) element); - } else if (element instanceof AppEngineStandardProjectElement) { - return ((AppEngineStandardProjectElement) element).getStyledLabel(); + if (element instanceof IProject && AppEngineContentProvider.isAppEngine((IProject) element)) { + return getAppEngineProjectText((IProject) element); + } else if (element instanceof AppEngineProjectElement) { + return ((AppEngineProjectElement) element).getStyledLabel(); } else if (element instanceof AppEngineResourceElement) { return ((AppEngineResourceElement) element).getStyledLabel(); } @@ -72,59 +64,59 @@ public StyledString getStyledText(Object element) { } @VisibleForTesting - static StyledString getAppEngineStandardProjectText(IProject project) { - // FIXME: this is grotty; can we not get the content provider? - IFile appEngineWeb = WebProjectUtil.findInWebInf(project, new Path("appengine-web.xml")); - if (appEngineWeb == null || !appEngineWeb.exists()) { - // continue on to the next - return null; - } - StyledString result = new StyledString(project.getName()); - try (InputStream input = appEngineWeb.getContents()) { - AppEngineDescriptor descriptor = AppEngineDescriptor.parse(input); - String qualifier = getVersionTuple(descriptor); + static StyledString getAppEngineProjectText(IProject project) { + try { + AppEngineProjectElement projectElement = AppEngineContentProvider.loadRepresentation(project); + StyledString result = new StyledString(project.getName()); + String qualifier = getVersionTuple(projectElement); if (qualifier.length() > 0) { result.append(" [", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$ result.append(qualifier.toString(), StyledString.QUALIFIER_STYLER); result.append("]", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$ } - } catch (IOException | CoreException | SAXException | AppEngineException ex) { + return result; + } catch (AppEngineException ex) { // ignore } - return result; + return null; // carry onto the next label provider } - /** Returns a project:service:version tuple from the appengine-web descriptor. */ + /** Returns a project:service:version tuple from the App Engine descriptor. */ @VisibleForTesting - static String getVersionTuple(AppEngineDescriptor descriptor) throws AppEngineException { + static String getVersionTuple(AppEngineProjectElement projectElement) { StringBuilder qualifier = new StringBuilder(); - if (descriptor != null) { - if (!Strings.isNullOrEmpty(descriptor.getProjectId())) { - qualifier.append(descriptor.getProjectId()); - } - if (!Strings.isNullOrEmpty(descriptor.getServiceId())) { - if (qualifier.length() > 0) { - qualifier.append(':'); - } - qualifier.append(descriptor.getServiceId()); + + String projectId = projectElement.getProjectId(); + if (!Strings.isNullOrEmpty(projectId)) { + qualifier.append(projectId); + } + + String serviceId = projectElement.getServiceId(); + if (!Strings.isNullOrEmpty(serviceId)) { + if (qualifier.length() > 0) { + qualifier.append(':'); } - if (!Strings.isNullOrEmpty(descriptor.getProjectVersion())) { - if (qualifier.length() > 0) { - qualifier.append(':'); - } - qualifier.append(descriptor.getProjectVersion()); + qualifier.append(serviceId); + } + + String projectVersion = projectElement.getProjectVersion(); + if (!Strings.isNullOrEmpty(projectVersion)) { + if (qualifier.length() > 0) { + qualifier.append(':'); } + qualifier.append(projectVersion); } return qualifier.toString(); } @Override public Image getImage(Object element) { - if (element instanceof IProject && AppEngineContentProvider.isStandard((IProject) element)) { + if (element instanceof IProject && AppEngineContentProvider.isAppEngine((IProject) element)) { return resources.createImage(AppEngineImages.APPENGINE_IMAGE_DESCRIPTOR); } else if (element instanceof DatastoreIndexesDescriptor) { return resources.createImage(SharedImages.DATASTORE_GREY_IMAGE_DESCRIPTOR); - } else if (element instanceof AppEngineResourceElement) { + } else if (element instanceof AppEngineProjectElement + || element instanceof AppEngineResourceElement) { // todo Get better images for these resource elements // CronDescriptor could be a timer/clock? // DenialOfServiceDescriptor could be a do-not-enter? diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineStandardProjectElement.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineProjectElement.java similarity index 63% rename from plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineStandardProjectElement.java rename to plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineProjectElement.java index f5ba879e6f..a0ffa7b28e 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineStandardProjectElement.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/AppEngineProjectElement.java @@ -18,11 +18,14 @@ import com.google.cloud.tools.appengine.AppEngineDescriptor; import com.google.cloud.tools.appengine.api.AppEngineException; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; +import com.google.cloud.tools.project.AppYaml; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import java.io.IOException; import java.io.InputStream; import java.util.Collection; @@ -40,10 +43,11 @@ /** * A model representation of an App Engine project. App Engine projects always have a descriptor - * (e.g., {@code appengine-web.xml}) that may provide their environment, runtime type, and Service - * ID. This element manages model representations of the various App Engine configuration files. + * ({@code app.yaml} or {@code appengine-web.xml}) that may provide their App Engine environment + * type (standard or flexible), runtime type, and Service ID. This element manages model elements + * representations of the various App Engine configuration files. */ -public class AppEngineStandardProjectElement implements IAdaptable { +public class AppEngineProjectElement implements IAdaptable { /** Special project file that describes the virtual folder layout used for building WARs. */ private static final IPath WTP_COMPONENT_PATH = @@ -53,9 +57,18 @@ public class AppEngineStandardProjectElement implements IAdaptable { private static final IPath WTP_FACETS_PATH = new Path(".settings/org.eclipse.wst.common.project.facet.core.xml"); // $NON-NLS-1$ + /** Special project file that records the project's facets. */ + private static final ImmutableSet APPENGINE_DESCRIPTOR_FILENAMES = + ImmutableSet.of("appengine-web.xml", "app.yaml"); //$NON-NLS-1$ //$NON-NLS-2$ + /** Factories to create model elements for the various App Engine configuration files. */ private static final Map> elementFactories = new ImmutableMap.Builder>() + .put("cron.yaml", file -> new CronDescriptor(file)) // $NON-NLS-1$ + .put("index.yaml", file -> new DatastoreIndexesDescriptor(file)) // $NON-NLS-1$ + .put("queue.yaml", file -> new TaskQueuesDescriptor(file)) // $NON-NLS-1$ + .put("dos.yaml", file -> new DenialOfServiceDescriptor(file)) // $NON-NLS-1$ + .put("dispatch.yaml", file -> new DispatchRoutingDescriptor(file)) // $NON-NLS-1$ .put("cron.xml", file -> new CronDescriptor(file)) // $NON-NLS-1$ .put("datastore-indexes.xml", file -> new DatastoreIndexesDescriptor(file)) // $NON-NLS-1$ .put("queue.xml", file -> new TaskQueuesDescriptor(file)) // $NON-NLS-1$ @@ -68,28 +81,39 @@ public class AppEngineStandardProjectElement implements IAdaptable { * * @throws AppEngineException when unable to parse the descriptor file ({@code appengine-web.xml}) */ - public static AppEngineStandardProjectElement create(IProject project) throws AppEngineException { - AppEngineStandardProjectElement appEngineProject = new AppEngineStandardProjectElement(project); + public static AppEngineProjectElement create(IProject project) throws AppEngineException { + AppEngineProjectElement appEngineProject = new AppEngineProjectElement(project); appEngineProject.reload(); return appEngineProject; } /** - * Find the App Engine descriptor ({@code appengine-web.xml}) for this project. + * Find the App Engine descriptor ({@code app.yaml} or {@code appengine-web.xml}) for this + * project. * * @throws AppEngineException if the descriptor cannot be found */ private static IFile findAppEngineDescriptor(IProject project) throws AppEngineException { - IFile descriptorFile = WebProjectUtil.findInWebInf(project, new Path("appengine-web.xml")); - if (descriptorFile == null || !descriptorFile.exists()) { - throw new AppEngineException("appengine-web.xml not found"); + // Which of app.yaml or appengine-web.xml should win? + + IFile descriptorFile = + AppEngineConfigurationUtil.findConfigurationFile(project, new Path("appengine-web.xml")); + if (descriptorFile != null && descriptorFile.exists()) { + return descriptorFile; } - return descriptorFile; + + descriptorFile = + AppEngineConfigurationUtil.findConfigurationFile(project, new Path("app.yaml")); + if (descriptorFile != null && descriptorFile.exists()) { + return descriptorFile; + } + throw new AppEngineException("App Engine descriptor not found"); } /** Return {@code true} if the changed files may result in a different virtual layout. */ @VisibleForTesting static boolean hasLayoutChanged(Collection changedFiles) { + Preconditions.checkNotNull(changedFiles); // the virtual layout may have been reconfigured, or no longer an App Engine project for (IFile changed : changedFiles) { IPath projectRelativePath = changed.getProjectRelativePath(); @@ -101,6 +125,17 @@ static boolean hasLayoutChanged(Collection changedFiles) { return false; } + /** + * Return {@code true} if the list of changed files includes an App Engine descriptor. This file + * may not necessarily be the resolved descriptor. + */ + public static boolean hasAppEngineDescriptor(Collection changedFiles) { + Preconditions.checkNotNull(changedFiles); + return Iterables.any( + changedFiles, + file -> file != null && APPENGINE_DESCRIPTOR_FILENAMES.contains(file.getName())); + } + private final IProject project; /** @@ -109,12 +144,26 @@ static boolean hasLayoutChanged(Collection changedFiles) { */ private IFile descriptorFile; - private AppEngineDescriptor descriptor; + private String projectId; + private String projectVersion; + private String serviceId; + + /** + * The value of the App Engine environment type (i.e., {@code standard} or {@code flex}). This + * usually corresponds to the {@code env:} value. + */ + private String environmentType; + + /** + * Return the App Engine runtime (e.g., java7, java8). This usually corresponds to the {@code + * } or {@code runtime:} value. + */ + private String runtime; /** Map of base-file-name → model-element pairs. */ private final Map configurations = new TreeMap<>(); - private AppEngineStandardProjectElement(IProject project) throws AppEngineException { + private AppEngineProjectElement(IProject project) throws AppEngineException { this.project = project; this.descriptorFile = findAppEngineDescriptor(project); } @@ -143,25 +192,45 @@ public AppEngineResourceElement[] getConfigurations() { return configurations.values().toArray(new AppEngineResourceElement[configurations.size()]); } - public String getRuntimeType() { - try { - String runtime = descriptor.getRuntime(); - return "standard: " + (Strings.isNullOrEmpty(runtime) ? "java7" : runtime); - } catch (AppEngineException ex) { - return null; - } + /** Return the GCP Project ID, or {@code null} if not specified. */ + public String getProjectId() { + return projectId; + } + + /** Return the GCP Project Version, or {@code null} if not specified. */ + public String getProjectVersion() { + return projectVersion; } - public AppEngineDescriptor getDescriptor() { - return descriptor; + /** + * Return the App Engine Service ID, or {@code null} if not specified (which is {@code + * "default"}). + */ + public String getServiceId() { + return serviceId; + } + + /** Return the App Engine environment type: {@code standard} or {@code flex}. */ + public String getEnvironmentType() { + return environmentType; + } + + /** + * Return the App Engine runtime type, which may depend on the {@link #getEnvironmentType() + * environment type}. + */ + public String getRuntime() { + return runtime; } public StyledString getStyledLabel() { StyledString result = new StyledString("App Engine"); - String qualifier = getRuntimeType(); - if (qualifier != null) { - result.append(" [" + qualifier + "]", StyledString.QUALIFIER_STYLER); - } + result.append(" [", StyledString.QUALIFIER_STYLER); + result.append(getEnvironmentType(), StyledString.QUALIFIER_STYLER); + result.append(": ", StyledString.QUALIFIER_STYLER); + result.append(getRuntime(), StyledString.QUALIFIER_STYLER); + result.append("]", StyledString.QUALIFIER_STYLER); + result.append(" - " + descriptorFile.getName(), StyledString.DECORATIONS_STYLER); return result; } @@ -177,8 +246,9 @@ public boolean resourcesChanged(Collection changedFiles) throws AppEngine boolean layoutChanged = hasLayoutChanged(changedFiles); // files may be newly exposed or removed boolean hasNewDescriptor = - layoutChanged && !descriptorFile.equals(findAppEngineDescriptor(project)); - + (layoutChanged || hasAppEngineDescriptor(changedFiles)) + && !descriptorFile.equals(findAppEngineDescriptor(project)); + if (changedFiles.contains(descriptorFile) || hasNewDescriptor) { // reload everything: e.g., may no longer be "default" reload(); @@ -226,12 +296,7 @@ public boolean resourcesChanged(Collection changedFiles) throws AppEngine /** Return {@code true} if this is the default service. */ private boolean isDefaultService() { - try { - return descriptor.getServiceId() == null || "default".equals(descriptor.getServiceId()); - } catch (AppEngineException ex) { - // ignore - return false; - } + return serviceId == null || "default".equals(serviceId); } /** @@ -242,8 +307,35 @@ private boolean isDefaultService() { private void reload() throws AppEngineException { descriptorFile = findAppEngineDescriptor(project); try (InputStream input = descriptorFile.getContents()) { - descriptor = AppEngineDescriptor.parse(input); + if ("app.yaml".equals(descriptorFile.getName())) { + AppYaml descriptor = AppYaml.parse(input); + projectId = descriptor.getProjectId(); + projectVersion = descriptor.getProjectVersion(); + serviceId = descriptor.getServiceId(); + // flex always has `env: flex`; we ignore Managed VM + environmentType = + Strings.isNullOrEmpty(descriptor.getEnvironmentType()) + ? "standard" + : descriptor.getEnvironmentType(); + runtime = descriptor.getRuntime(); + if (Strings.isNullOrEmpty(runtime)) { + throw new AppEngineException("missing runtime: element"); + } + } else { + AppEngineDescriptor descriptor = AppEngineDescriptor.parse(input); + projectId = descriptor.getProjectId(); + projectVersion = descriptor.getProjectVersion(); + serviceId = descriptor.getServiceId(); + environmentType = "standard"; + runtime = + Strings.isNullOrEmpty(descriptor.getRuntime()) ? "java7" : descriptor.getRuntime(); + } } catch (IOException | SAXException | CoreException ex) { + projectId = null; + projectVersion = null; + serviceId = null; + environmentType = null; + runtime = null; configurations.clear(); throw new AppEngineException( "Unable to load appengine descriptor from " + descriptorFile, ex); @@ -284,7 +376,8 @@ private AppEngineResourceElement updateElement( // Check that each model element, if present, corresponds to the current configuration file. // Rebuild the element representation using the provided element creator, or remove // it, as required. - IFile configurationFile = WebProjectUtil.findInWebInf(project, new Path(baseName)); + IFile configurationFile = + AppEngineConfigurationUtil.findConfigurationFile(project, new Path(baseName)); if (configurationFile == null || !configurationFile.exists()) { // remove the element e.g., file has disappeared return null; diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/CronDescriptor.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/CronDescriptor.java index 9a9bfa32f8..9edb617a37 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/CronDescriptor.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/CronDescriptor.java @@ -29,6 +29,7 @@ public CronDescriptor(IFile file) { @Override public StyledString getStyledLabel() { - return new StyledString("Scheduled Tasks"); + return new StyledString("Scheduled Tasks") + .append(" - " + getFile().getName(), StyledString.DECORATIONS_STYLER); } } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DatastoreIndexesDescriptor.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DatastoreIndexesDescriptor.java index 50282d0529..35d372d40d 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DatastoreIndexesDescriptor.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DatastoreIndexesDescriptor.java @@ -30,7 +30,8 @@ public DatastoreIndexesDescriptor(IFile datastoreIndexes) { @Override public StyledString getStyledLabel() { - return new StyledString("Datastore Indexes"); + return new StyledString("Datastore Indexes") + .append(" - " + getFile().getName(), StyledString.DECORATIONS_STYLER); } } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DenialOfServiceDescriptor.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DenialOfServiceDescriptor.java index df940fe82e..4c9f4056fe 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DenialOfServiceDescriptor.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DenialOfServiceDescriptor.java @@ -29,6 +29,7 @@ public DenialOfServiceDescriptor(IFile file) { @Override public StyledString getStyledLabel() { - return new StyledString("Denial of Service Protection"); + return new StyledString("Denial of Service Protection") + .append(" - " + getFile().getName(), StyledString.DECORATIONS_STYLER); } } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DispatchRoutingDescriptor.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DispatchRoutingDescriptor.java index bbda976e4b..22c996ede8 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DispatchRoutingDescriptor.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/DispatchRoutingDescriptor.java @@ -29,7 +29,8 @@ public DispatchRoutingDescriptor(IFile file) { @Override public StyledString getStyledLabel() { - return new StyledString("Dispatch Routing Rules"); + return new StyledString("Dispatch Routing Rules") + .append(" - " + getFile().getName(), StyledString.DECORATIONS_STYLER); } } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/TaskQueuesDescriptor.java b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/TaskQueuesDescriptor.java index e109887c16..076e53feea 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/TaskQueuesDescriptor.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.facets/src/com/google/cloud/tools/eclipse/appengine/facets/ui/navigator/model/TaskQueuesDescriptor.java @@ -29,6 +29,7 @@ public TaskQueuesDescriptor(IFile file) { @Override public StyledString getStyledLabel() { - return new StyledString("Task Queue Definitions"); + return new StyledString("Task Queue Definitions") + .append(" - " + getFile().getName(), StyledString.DECORATIONS_STYLER); } } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/server/DatastoreIndexUpdateData.java b/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/server/DatastoreIndexUpdateData.java index d894847a49..243f14e612 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/server/DatastoreIndexUpdateData.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/server/DatastoreIndexUpdateData.java @@ -16,7 +16,7 @@ package com.google.cloud.tools.eclipse.appengine.localserver.server; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.common.annotations.VisibleForTesting; import java.io.IOException; import java.util.logging.Level; @@ -61,8 +61,10 @@ static DatastoreIndexUpdateData detect(ILaunchConfiguration configuration, IServ return null; } // datastore-indexes-auto.xml may be generated even if datastore-indexes.xml does not exist - IFile datastoreIndexesXml = WebProjectUtil.findInWebInf(defaultService.getProject(), - new org.eclipse.core.runtime.Path("datastore-indexes.xml")); + IFile datastoreIndexesXml = + AppEngineConfigurationUtil.findConfigurationFile( + defaultService.getProject(), + new org.eclipse.core.runtime.Path("datastore-indexes.xml")); if (datastoreIndexesXml != null && datastoreIndexesXml.exists()) { long sourceTimestamp = datastoreIndexesXml.getLocalTimeStamp(); diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/server/ModuleUtils.java b/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/server/ModuleUtils.java index 595779674c..492db54142 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/server/ModuleUtils.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/server/ModuleUtils.java @@ -19,7 +19,7 @@ import com.google.api.client.util.Preconditions; import com.google.cloud.tools.appengine.AppEngineDescriptor; import com.google.cloud.tools.appengine.api.AppEngineException; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; @@ -48,7 +48,8 @@ public class ModuleUtils { */ public static String getServiceId(IModule module) { IFile descriptorFile = - WebProjectUtil.findInWebInf(module.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + module.getProject(), new Path("appengine-web.xml")); if (descriptorFile != null) { try (InputStream contents = descriptorFile.getContents()) { AppEngineDescriptor descriptor = AppEngineDescriptor.parse(contents); diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/ui/DatastoreIndexesUpdatedStatusHandler.java b/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/ui/DatastoreIndexesUpdatedStatusHandler.java index 3cd7c9fdae..a18a97aa82 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/ui/DatastoreIndexesUpdatedStatusHandler.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.localserver/src/com/google/cloud/tools/eclipse/appengine/localserver/ui/DatastoreIndexesUpdatedStatusHandler.java @@ -17,17 +17,15 @@ package com.google.cloud.tools.eclipse.appengine.localserver.ui; import com.google.api.client.util.Preconditions; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.localserver.Messages; import com.google.cloud.tools.eclipse.appengine.localserver.server.DatastoreIndexUpdateData; import com.google.cloud.tools.eclipse.util.status.StatusUtil; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; -import java.nio.charset.StandardCharsets; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.compare.BufferedContent; @@ -123,13 +121,11 @@ public Object handleStatus(IStatus status, Object source) throws CoreException { /** Create a new empty {@code datastore-indexes.xml} for the given project. */ private IFile createNewDatastoreIndexesXml(IProject project, IProgressMonitor monitor) throws CoreException { - InputStream contents = - new ByteArrayInputStream(EMPTY_DATASTORE_INDEXES_XML.getBytes(StandardCharsets.UTF_8)); IFile datastoreIndexesXml = - WebProjectUtil.createFileInWebInf( + AppEngineConfigurationUtil.createConfigurationFile( project, - new Path("datastore-indexes.xml"), //$NON-NLS-1$ - contents, + new Path("datastore-indexes.xml"), // $NON-NLS-1$ + EMPTY_DATASTORE_INDEXES_XML, false /* overwrite */, monitor); return datastoreIndexesXml; diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardFacetVersionChangeTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardFacetVersionChangeTest.java index e5af83ea2e..ff874efc13 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardFacetVersionChangeTest.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardFacetVersionChangeTest.java @@ -24,8 +24,8 @@ import com.google.cloud.tools.appengine.AppEngineDescriptor; import com.google.cloud.tools.appengine.api.AppEngineException; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import com.google.cloud.tools.eclipse.test.util.project.ProjectUtils; import com.google.cloud.tools.eclipse.test.util.project.TestProjectCreator; import java.io.IOException; @@ -124,7 +124,8 @@ public void testChange_AESJ8_AESJ7andJava7() throws CoreException, IOException, private static AppEngineDescriptor parseDescriptor(IFacetedProject project) throws IOException, CoreException, SAXException { IFile descriptorFile = - WebProjectUtil.findInWebInf(project.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + project.getProject(), new Path("appengine-web.xml")); assertNotNull("appengine-web.xml not found", descriptorFile); assertTrue("appengine-web.xml does not exist", descriptorFile.exists()); diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineWebBuilderTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineWebBuilderTest.java index 27faaea5da..be17c92237 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineWebBuilderTest.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineWebBuilderTest.java @@ -21,8 +21,8 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import com.google.cloud.tools.eclipse.test.util.project.ProjectUtils; import com.google.cloud.tools.eclipse.test.util.project.TestProjectCreator; import java.util.Collections; @@ -84,8 +84,9 @@ public void testAddJava8Runtime() throws CoreException { .getFacetedProject(); assertProjectHasBuilder(); - IFile appEngineWebDescriptor = WebProjectUtil.findInWebInf(testProject.getProject(), - new Path("appengine-web.xml")); + IFile appEngineWebDescriptor = + AppEngineConfigurationUtil.findConfigurationFile( + testProject.getProject(), new Path("appengine-web.xml")); assertTrue("should have appengine-web.xml", appEngineWebDescriptor != null && appEngineWebDescriptor.exists()); @@ -109,7 +110,8 @@ public void testRemovingJava8Runtime() throws CoreException { assertProjectHasBuilder(); IFile appEngineWebDescriptor = - WebProjectUtil.findInWebInf(testProject.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + testProject.getProject(), new Path("appengine-web.xml")); assertTrue("should have appengine-web.xml", appEngineWebDescriptor != null && appEngineWebDescriptor.exists()); @@ -130,7 +132,8 @@ public void testRemovingJava8Runtime_webFacet() throws CoreException { assertProjectHasBuilder(); IFile appEngineWebDescriptor = - WebProjectUtil.findInWebInf(testProject.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + testProject.getProject(), new Path("appengine-web.xml")); assertTrue("should have appengine-web.xml", appEngineWebDescriptor != null && appEngineWebDescriptor.exists()); diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/ConversionTests.java b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/ConversionTests.java index 7279c4fd49..7d829b2767 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/ConversionTests.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8.test/src/com/google/cloud/tools/eclipse/appengine/standard/java8/ConversionTests.java @@ -24,8 +24,8 @@ import com.google.cloud.tools.appengine.AppEngineDescriptor; import com.google.cloud.tools.appengine.api.AppEngineException; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import com.google.cloud.tools.eclipse.appengine.facets.convert.AppEngineStandardProjectConvertJob; import com.google.cloud.tools.eclipse.test.util.project.TestProjectCreator; import com.google.cloud.tools.eclipse.util.io.ResourceUtils; @@ -389,7 +389,8 @@ private void createAppEngineWebWithJava8Runtime(IFacetedProject project) throws private void assertJava8Runtime(IFacetedProject project) throws IOException, SAXException, CoreException, AppEngineException { IFile appengineWebXml = - WebProjectUtil.findInWebInf(project.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + project.getProject(), new Path("appengine-web.xml")); assertNotNull("appengine-web.xml is missing", appengineWebXml); assertTrue("appengine-web.xml does not exist", appengineWebXml.exists()); try (InputStream contents = appengineWebXml.getContents()) { @@ -409,7 +410,8 @@ private void assertJava8Runtime(IFacetedProject project) private void assertNoJava8Runtime(IFacetedProject project) throws IOException, SAXException, CoreException, AppEngineException { IFile appengineWebXml = - WebProjectUtil.findInWebInf(project.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + project.getProject(), new Path("appengine-web.xml")); assertNotNull("appengine-web.xml is missing", appengineWebXml); assertTrue("appengine-web.xml does not exist", appengineWebXml.exists()); try (InputStream contents = appengineWebXml.getContents()) { diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardFacetChangeListener.java b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardFacetChangeListener.java index 63933bed67..eeee6ad26d 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardFacetChangeListener.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardFacetChangeListener.java @@ -18,8 +18,8 @@ import com.google.cloud.tools.appengine.AppEngineDescriptor; import com.google.cloud.tools.appengine.api.AppEngineException; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import java.io.IOException; import java.io.InputStream; import java.util.logging.Level; @@ -156,7 +156,8 @@ private static void removeAppEngineWebBuilder(IProject project) { */ private static IFile findDescriptor(IFacetedProject project) { IFile descriptor = - WebProjectUtil.findInWebInf(project.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + project.getProject(), new Path("appengine-web.xml")); return descriptor; } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardJre8ProjectFacetDetector.java b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardJre8ProjectFacetDetector.java index c9ba8e2414..329e3fc313 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardJre8ProjectFacetDetector.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineStandardJre8ProjectFacetDetector.java @@ -18,9 +18,9 @@ import com.google.cloud.tools.appengine.AppEngineDescriptor; import com.google.cloud.tools.appengine.api.AppEngineException; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; import com.google.cloud.tools.eclipse.appengine.facets.FacetUtil; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import com.google.cloud.tools.eclipse.util.status.StatusUtil; import java.io.IOException; import java.io.InputStream; @@ -60,7 +60,8 @@ public void detect(IFacetedProjectWorkingCopy workingCopy, IProgressMonitor moni } IFile appEngineWebXml = - WebProjectUtil.findInWebInf(workingCopy.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + workingCopy.getProject(), new Path("appengine-web.xml")); if (appEngineWebXml == null || !appEngineWebXml.exists()) { return; } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineWebBuilder.java b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineWebBuilder.java index b150a506b0..d0bc4a6ebc 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineWebBuilder.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/AppEngineWebBuilder.java @@ -18,8 +18,8 @@ import com.google.cloud.tools.appengine.AppEngineDescriptor; import com.google.cloud.tools.appengine.api.AppEngineException; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import com.google.cloud.tools.eclipse.util.MavenUtils; import java.io.IOException; import java.io.InputStream; @@ -60,7 +60,8 @@ protected IProject[] build(int kind, Map args, IProgressMonitor return null; } IFile appEngineWebDescriptor = - WebProjectUtil.findInWebInf(project.getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + project.getProject(), new Path("appengine-web.xml")); if (appEngineWebDescriptor == null || !appEngineWebDescriptor.exists()) { logger.warning(getProject() + ": no build required: missing appengine-web.xml"); return null; diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/ConvertToJava8RuntimeHandler.java b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/ConvertToJava8RuntimeHandler.java index bc071f1d82..f2b96a185d 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/ConvertToJava8RuntimeHandler.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/ConvertToJava8RuntimeHandler.java @@ -16,7 +16,7 @@ package com.google.cloud.tools.eclipse.appengine.standard.java8; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.ui.util.ProjectFromSelectionHelper; import com.google.common.base.Preconditions; import java.util.List; @@ -46,14 +46,15 @@ public class ConvertToJava8RuntimeHandler extends AbstractHandler { public Object execute(ExecutionEvent event) throws ExecutionException { List projects = ProjectFromSelectionHelper.getProjects(event); Preconditions.checkArgument(!projects.isEmpty()); - Job updateJob = new WorkspaceJob(Messages.getString("reconfiguringToJava8")) { //$NON-NLS-1$ + Job updateJob = new WorkspaceJob(Messages.getString("reconfiguringToJava8")) { // $NON-NLS-1$ @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, projects.size()); for (IProject project : projects) { progress.subTask( - Messages.getString("reconfiguringProject", project.getName())); //$NON-NLS-1$ - IFile appEngineWebXml = WebProjectUtil.findInWebInf(project, APPENGINE_DESCRIPTOR); + Messages.getString("reconfiguringProject", project.getName())); // $NON-NLS-1$ + IFile appEngineWebXml = + AppEngineConfigurationUtil.findConfigurationFile(project, APPENGINE_DESCRIPTOR); if (appEngineWebXml != null) { // add the and the rest should be handled for us AppEngineDescriptorTransform.addJava8Runtime(appEngineWebXml); diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/m2e/AppEngineStandardProjectDetector.java b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/m2e/AppEngineStandardProjectDetector.java index 56c4968fd4..f01dfe1d3a 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/m2e/AppEngineStandardProjectDetector.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.standard.java8/src/com/google/cloud/tools/eclipse/appengine/standard/java8/m2e/AppEngineStandardProjectDetector.java @@ -16,8 +16,8 @@ package com.google.cloud.tools.eclipse.appengine.standard.java8.m2e; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -41,7 +41,9 @@ public void configure(ProjectConfigurationRequest request, IProgressMonitor moni if (facetedProject == null || facetedProject.hasProjectFacet(AppEngineStandardFacet.FACET)) { return; } - IFile appEngineWebXml = WebProjectUtil.findInWebInf(project, new Path("appengine-web.xml")); //$NON-NLS-1$ + IFile appEngineWebXml = + AppEngineConfigurationUtil.findConfigurationFile( + project, new Path("appengine-web.xml")); // $NON-NLS-1$ if (appEngineWebXml == null || !appEngineWebXml.exists()) { return; } diff --git a/plugins/com.google.cloud.tools.eclipse.appengine.validation.test/src/com/google/cloud/tools/eclipse/appengine/validation/AppEngineWebXmlValidationTest.java b/plugins/com.google.cloud.tools.eclipse.appengine.validation.test/src/com/google/cloud/tools/eclipse/appengine/validation/AppEngineWebXmlValidationTest.java index 91df09d5c2..29e61b2d08 100644 --- a/plugins/com.google.cloud.tools.eclipse.appengine.validation.test/src/com/google/cloud/tools/eclipse/appengine/validation/AppEngineWebXmlValidationTest.java +++ b/plugins/com.google.cloud.tools.eclipse.appengine.validation.test/src/com/google/cloud/tools/eclipse/appengine/validation/AppEngineWebXmlValidationTest.java @@ -18,8 +18,8 @@ import static org.junit.Assert.assertTrue; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import com.google.cloud.tools.eclipse.test.util.project.ProjectUtils; import com.google.cloud.tools.eclipse.test.util.project.TestProjectCreator; import java.io.ByteArrayInputStream; @@ -43,7 +43,7 @@ public class AppEngineWebXmlValidationTest { public void testStagingElementsInAppEngineWebXml() throws CoreException { IProject project = projectCreator.getProject(); IFile appEngineWebXml = - WebProjectUtil.findInWebInf(project, new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile(project, new Path("appengine-web.xml")); assertTrue(appEngineWebXml.exists()); String contents = "\n" diff --git a/plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/project/TestProjectCreator.java b/plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/project/TestProjectCreator.java index 44db8d14a9..facd78627c 100644 --- a/plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/project/TestProjectCreator.java +++ b/plugins/com.google.cloud.tools.eclipse.test.util/src/com/google/cloud/tools/eclipse/test/util/project/TestProjectCreator.java @@ -18,9 +18,9 @@ import static org.junit.Assert.assertTrue; +import com.google.cloud.tools.eclipse.appengine.facets.AppEngineConfigurationUtil; import com.google.cloud.tools.eclipse.appengine.facets.AppEngineStandardFacet; import com.google.cloud.tools.eclipse.appengine.facets.FacetUtil; -import com.google.cloud.tools.eclipse.appengine.facets.WebProjectUtil; import com.google.cloud.tools.eclipse.test.util.ThreadDumpingWatchdog; import com.google.cloud.tools.eclipse.util.ClasspathUtil; import com.google.common.base.Preconditions; @@ -195,7 +195,8 @@ private void addFacets() throws CoreException { private void setAppEngineServiceId(String serviceId) throws CoreException { IFile appEngineWebXml = - WebProjectUtil.findInWebInf(getProject(), new Path("appengine-web.xml")); + AppEngineConfigurationUtil.findConfigurationFile( + getProject(), new Path("appengine-web.xml")); assertTrue("Project should have AppEngine Standard facet", appEngineWebXml.exists()); String contents = "\n" + "" + serviceId + "\n\n";