summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajeev Dayal <rdayal@google.com>2014-06-12 23:26:07 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-06-10 21:55:12 +0000
commitf0dc41bee32d977ac00a58743be834ad4e9a56e1 (patch)
tree1407ba1da7a7e58e9ac7f293f1a1cb305cb00e41
parent0c428ebe257f644d52d732d4d7ff5abc9efa75f4 (diff)
parentc621a13b217326dc0811e9fd436e35ddbbd2eabf (diff)
downloadcloud-f0dc41bee32d977ac00a58743be834ad4e9a56e1.tar.gz
Merge "Builder Model for Appengine Gradle Projects" into idea133
-rw-r--r--google-cloud-tools.iml9
-rw-r--r--lib/gradle-appengine-builder-model-0.1.0.jarbin0 -> 1944 bytes
-rw-r--r--src/META-INF/plugin.xml10
-rw-r--r--src/com/google/gct/idea/appengine/gradle/facet/AppEngineGradleFacet.java13
-rw-r--r--src/com/google/gct/idea/appengine/gradle/project/AppEngineGradleProjectResolver.java67
-rw-r--r--src/com/google/gct/idea/appengine/gradle/project/IdeaAppEngineProject.java57
-rw-r--r--src/com/google/gct/idea/appengine/gradle/service/AppEngineGradleProjectDataService.java114
-rw-r--r--src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.form2
-rw-r--r--src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.java16
9 files changed, 283 insertions, 5 deletions
diff --git a/google-cloud-tools.iml b/google-cloud-tools.iml
index 706f6e1..2613b4a 100644
--- a/google-cloud-tools.iml
+++ b/google-cloud-tools.iml
@@ -45,6 +45,15 @@
<SOURCES />
</library>
</orderEntry>
+ <orderEntry type="module-library">
+ <library>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/lib/gradle-appengine-builder-model-0.1.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
</component>
</module>
diff --git a/lib/gradle-appengine-builder-model-0.1.0.jar b/lib/gradle-appengine-builder-model-0.1.0.jar
new file mode 100644
index 0000000..3f5077a
--- /dev/null
+++ b/lib/gradle-appengine-builder-model-0.1.0.jar
Binary files differ
diff --git a/src/META-INF/plugin.xml b/src/META-INF/plugin.xml
index 436df77..e05db4d 100644
--- a/src/META-INF/plugin.xml
+++ b/src/META-INF/plugin.xml
@@ -23,11 +23,17 @@
<project-components>
</project-components>
+ <depends>org.jetbrains.plugins.gradle</depends>
+ <extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
+ <projectResolve implementation="com.google.gct.idea.appengine.gradle.project.AppEngineGradleProjectResolver"/>
+ </extensions>
+
<extensions defaultExtensionNs="com.intellij">
- <!-- facet disabled for now
<facetType implementation="com.google.gct.idea.appengine.gradle.facet.AppEngineGradleFacetType"/>
+ <!-- facet detector disabled for now, use the gradle project importer to add the facet
<framework.detector implementation="com.google.gct.idea.appengine.gradle.facet.AppEngineFrameworkDetector"/>
- -->
+ -->
+ <externalProjectDataService implementation="com.google.gct.idea.appengine.gradle.service.AppEngineGradleProjectDataService" />
<!-- Temporarily disable
<applicationConfigurable instance="com.google.gct.idea.appengine.synchronization.SampleSyncConfigurable"></applicationConfigurable>
diff --git a/src/com/google/gct/idea/appengine/gradle/facet/AppEngineGradleFacet.java b/src/com/google/gct/idea/appengine/gradle/facet/AppEngineGradleFacet.java
index 952c9eb..08ef0cd 100644
--- a/src/com/google/gct/idea/appengine/gradle/facet/AppEngineGradleFacet.java
+++ b/src/com/google/gct/idea/appengine/gradle/facet/AppEngineGradleFacet.java
@@ -15,6 +15,7 @@
*/
package com.google.gct.idea.appengine.gradle.facet;
+import com.google.gct.idea.appengine.gradle.project.IdeaAppEngineProject;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetManager;
import com.intellij.facet.FacetType;
@@ -37,8 +38,7 @@ public class AppEngineGradleFacet extends Facet<AppEngineGradleFacetConfiguratio
public static final FacetTypeId<AppEngineGradleFacet> TYPE_ID = new FacetTypeId<AppEngineGradleFacet>(ID);
- // Need to modify this to reference the Model for an AppEngine Gradle project
- // private IdeaGradleProject myGradleProject;
+ private IdeaAppEngineProject myIdeaAppEngineProject;
@Nullable
public static AppEngineGradleFacet getInstance(@NotNull Module module) {
@@ -62,4 +62,13 @@ public class AppEngineGradleFacet extends Facet<AppEngineGradleFacetConfiguratio
if (module == null) return null;
return FacetManager.getInstance(module).getFacetByType(TYPE_ID);
}
+
+ public IdeaAppEngineProject getIdeaAppEngineProject() {
+ return myIdeaAppEngineProject;
+ }
+
+ public void setIdeaAppEngineProject(IdeaAppEngineProject ideaAppEngineProject) {
+ myIdeaAppEngineProject = ideaAppEngineProject;
+ }
+
}
diff --git a/src/com/google/gct/idea/appengine/gradle/project/AppEngineGradleProjectResolver.java b/src/com/google/gct/idea/appengine/gradle/project/AppEngineGradleProjectResolver.java
new file mode 100644
index 0000000..e226410
--- /dev/null
+++ b/src/com/google/gct/idea/appengine/gradle/project/AppEngineGradleProjectResolver.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.gct.idea.appengine.gradle.project;
+
+import com.google.appengine.gradle.model.AppEngineModel;
+import com.google.common.collect.Sets;
+import com.google.gct.idea.appengine.gradle.service.AppEngineGradleProjectDataService;
+
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.externalSystem.util.Order;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension;
+
+import org.gradle.tooling.model.idea.IdeaModule;
+
+import java.io.File;
+import java.util.Set;
+
+/**
+ * Project Resolved called during gradle import, it adds an appengine module key so the
+ * {@link com.google.gct.idea.appengine.gradle.service.AppEngineGradleProjectDataService} can identify the module and add metadata
+ */
+@Order(ExternalSystemConstants.UNORDERED)
+public class AppEngineGradleProjectResolver extends AbstractProjectResolverExtension {
+
+ public AppEngineGradleProjectResolver() {}
+
+ /** Identify modules that can populate the AppEngineModule gradle builder model */
+ @Override
+ public void populateModuleExtraModels(@NotNull IdeaModule gradleModule, @NotNull DataNode<ModuleData> ideModule) {
+
+ File moduleFilePath = new File(FileUtil.toSystemDependentName(ideModule.getData().getModuleFilePath()));
+ File moduleRootDirPath = moduleFilePath.getParentFile();
+
+ AppEngineModel appEngineModel = resolverCtx.getExtraProject(gradleModule, AppEngineModel.class);
+ if (appEngineModel != null) {
+ IdeaAppEngineProject ideaAppEngineProject =
+ new IdeaAppEngineProject(gradleModule.getName(), moduleRootDirPath, appEngineModel);
+ ideModule.createChild(AppEngineGradleProjectDataService.IDE_APP_ENGINE_PROJECT, ideaAppEngineProject);
+ }
+
+ nextResolver.populateModuleExtraModels(gradleModule, ideModule);
+ }
+
+ /** AppEngineModel is the only class we really care about in our resolver */
+ @Override
+ @NotNull
+ public Set<Class> getExtraProjectModelClasses() {
+ return Sets.<Class>newHashSet(AppEngineModel.class);
+ }
+}
diff --git a/src/com/google/gct/idea/appengine/gradle/project/IdeaAppEngineProject.java b/src/com/google/gct/idea/appengine/gradle/project/IdeaAppEngineProject.java
new file mode 100644
index 0000000..97a0270
--- /dev/null
+++ b/src/com/google/gct/idea/appengine/gradle/project/IdeaAppEngineProject.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.gct.idea.appengine.gradle.project;
+
+import com.google.appengine.gradle.model.AppEngineModel;
+
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * Project wrapper for App Engine Gradle Projects
+ */
+public class IdeaAppEngineProject {
+ @NotNull private final String myModuleName;
+ @NotNull private final VirtualFile myRootDir;
+ @NotNull private final AppEngineModel myDelegate;
+
+ public IdeaAppEngineProject(@NotNull String moduleName, @NotNull File rootDir, @NotNull AppEngineModel delegate) {
+ myModuleName = moduleName;
+ VirtualFile found = VfsUtil.findFileByIoFile(rootDir, true);
+ // the module's root directory can never be null.
+ assert found != null;
+ myRootDir = found;
+ myDelegate = delegate;
+ }
+
+ @NotNull
+ public String getModuleName() {
+ return myModuleName;
+ }
+
+ @NotNull
+ public VirtualFile getRootDir() {
+ return myRootDir;
+ }
+
+ @NotNull
+ public AppEngineModel getDelegate() {
+ return myDelegate;
+ }
+}
diff --git a/src/com/google/gct/idea/appengine/gradle/service/AppEngineGradleProjectDataService.java b/src/com/google/gct/idea/appengine/gradle/service/AppEngineGradleProjectDataService.java
new file mode 100644
index 0000000..36b25de
--- /dev/null
+++ b/src/com/google/gct/idea/appengine/gradle/service/AppEngineGradleProjectDataService.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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.gct.idea.appengine.gradle.service;
+
+import com.android.tools.idea.gradle.AndroidProjectKeys;
+import com.android.tools.idea.gradle.GradleSyncState;
+import com.google.common.collect.Maps;
+import com.google.gct.idea.appengine.gradle.facet.AppEngineGradleFacet;
+import com.google.gct.idea.appengine.gradle.project.IdeaAppEngineProject;
+
+import com.intellij.facet.FacetManager;
+import com.intellij.facet.ModifiableFacetModel;
+import com.intellij.openapi.application.RunResult;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.Key;
+import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Add necessary configuration information to an appengine modules identified by
+ * {@link com.google.gct.idea.appengine.gradle.project.AppEngineGradleProjectResolver}
+ */
+public class AppEngineGradleProjectDataService implements ProjectDataService<IdeaAppEngineProject, Void> {
+
+ private static final Logger LOG = Logger.getInstance(AppEngineGradleProjectDataService.class);
+ // TODO: move this somewhere else, maybe a keys file
+ @NotNull public static final Key<IdeaAppEngineProject> IDE_APP_ENGINE_PROJECT =
+ Key.create(IdeaAppEngineProject.class, AndroidProjectKeys.IDE_ANDROID_PROJECT.getProcessingWeight() + 10);
+
+ @NotNull
+ @Override
+ public Key<IdeaAppEngineProject> getTargetDataKey() {
+ return IDE_APP_ENGINE_PROJECT;
+ }
+
+ /** Add facet to App Engine module on imported modules */
+ @Override
+ public void importData(@NotNull final Collection<DataNode<IdeaAppEngineProject>> toImport,
+ @NotNull final Project project, boolean synchronous) {
+ if (toImport.isEmpty()) {
+ return;
+ }
+
+ RunResult result = new WriteCommandAction.Simple(project) {
+ @Override
+ protected void run() throws Throwable {
+ Map<String, IdeaAppEngineProject> importModulesMap = indexByModuleName(toImport);
+ for (Module module : ModuleManager.getInstance(project).getModules()) {
+ if (importModulesMap.containsKey(module.getName())) {
+ addAppEngineGradleFacet(importModulesMap.get(module.getName()), module);
+ }
+ }
+ }
+ }.execute();
+ Throwable error = result.getThrowable();
+ if (error != null) {
+ LOG.error(String.format("Failed to set up App Engine Gradle Modules"));
+ GradleSyncState.getInstance(project).syncFailed(error.getMessage());
+ }
+ }
+
+ @Override
+ public void removeData(@NotNull Collection<? extends Void> toRemove, @NotNull Project project, boolean synchronous) {
+
+ }
+
+ private static void addAppEngineGradleFacet(IdeaAppEngineProject ideaAppEngineProject, Module appEngineModule) {
+ //Module does not have AppEngine-Gradle facet. Create one and add it.
+ FacetManager facetManager = FacetManager.getInstance(appEngineModule);
+ ModifiableFacetModel model = facetManager.createModifiableModel();
+ AppEngineGradleFacet facet = AppEngineGradleFacet.getInstance(appEngineModule);
+ if (facet == null) {
+ try {
+ facet = facetManager.createFacet(AppEngineGradleFacet.getFacetType(), AppEngineGradleFacet.NAME, null);
+ model.addFacet(facet);
+ }
+ finally {
+ model.commit();
+ }
+ }
+ facet.setIdeaAppEngineProject(ideaAppEngineProject);
+ }
+
+ @NotNull
+ private static Map<String, IdeaAppEngineProject> indexByModuleName(@NotNull Collection<DataNode<IdeaAppEngineProject>> dataNodes) {
+ Map<String, IdeaAppEngineProject> index = Maps.newHashMap();
+ for (DataNode<IdeaAppEngineProject> d : dataNodes) {
+ IdeaAppEngineProject appEngineProject = d.getData();
+ index.put(appEngineProject.getModuleName(), appEngineProject);
+ }
+ return index;
+ }
+}
diff --git a/src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.form b/src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.form
index 2134d3a..aef286c 100644
--- a/src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.form
+++ b/src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.form
@@ -3,7 +3,7 @@
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="17" y="25" width="500" height="152"/>
+ <xy x="17" y="25" width="500" height="169"/>
</constraints>
<properties/>
<border type="none"/>
diff --git a/src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.java b/src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.java
index f9c7621..b77872b 100644
--- a/src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.java
+++ b/src/com/google/gct/idea/appengine/run/AppEngineRunConfigurationSettingsEditor.java
@@ -15,6 +15,8 @@
*/
package com.google.gct.idea.appengine.run;
+import com.google.appengine.gradle.model.AppEngineModel;
+import com.google.gct.idea.appengine.gradle.facet.AppEngineGradleFacet;
import com.intellij.execution.ui.ConfigurationModuleSelector;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.options.ConfigurationException;
@@ -23,6 +25,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import org.jetbrains.annotations.NotNull;
+import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
@@ -49,6 +52,19 @@ public class AppEngineRunConfigurationSettingsEditor extends SettingsEditor<AppE
FileChooserDescriptorFactory.createSingleFolderDescriptor());
}
+ // TODO: unused currently, but useful once gradle facet for App Engine is completely set up.
+ protected void syncWithBuildFile() {
+ AppEngineGradleFacet facet = AppEngineGradleFacet.getInstance(moduleSelector.getModule());
+ if(facet != null) {
+ // proof of concept of usefulness of Gradle model
+ AppEngineModel model = facet.getIdeaAppEngineProject().getDelegate();
+ myServerPortField.setText(model.getHttpPort().toString());
+ myServerAddressField.setText(model.getHttpAddress());
+ myAppEngineSdkField.setText(model.getAppEngineSdkRoot());
+ myWarPathField.setText(model.getWarDir().getAbsolutePath());
+ }
+ }
+
@Override
protected void resetEditorFrom(AppEngineRunConfiguration configuration) {
if (configuration.getSdkPath() != null) {