From 7dc476d4c6e5b6b0d8bcccc3c32cb8da223ed399 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Thu, 30 Jan 2014 11:48:27 +0400 Subject: [PATCH] Gradle: Module builder updated. * New Module now adds module to the respective gradle project using settings.gradle inclusion * Support for *.ipr (file based) project format added MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit related issue: IDEA-118040 Gradle: for a project with dot in its name a new .iml file with different name is сreated after project reopening --- .../i18n/ExternalSystemBundle.properties | 1 + .../wizard/AbstractExternalModuleBuilder.java | 76 +------ .../wizard/SelectExternalProjectStep.java | 3 + ...stractImportFromExternalSystemControl.java | 27 ++- .../settings/ExternalSystemConfigLocator.java | 12 ++ .../util/ExternalSystemUtil.java | 33 ++- ...Gradle Build Script with wrapper.gradle.ft | 4 +- .../internal/Gradle Settings merge.gradle.ft | 6 + .../internal/Gradle Settings.gradle.ft | 11 + .../project/wizard/GradleModuleBuilder.java | 195 ++++++++++++++++-- .../service/settings/GradleConfigLocator.java | 22 ++ 11 files changed, 278 insertions(+), 112 deletions(-) create mode 100644 plugins/gradle/resources/fileTemplates/internal/Gradle Settings merge.gradle.ft create mode 100644 plugins/gradle/resources/fileTemplates/internal/Gradle Settings.gradle.ft diff --git a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties index 9872721bc57a..e195238eec95 100644 --- a/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties +++ b/platform/external-system-api/resources/i18n/ExternalSystemBundle.properties @@ -10,6 +10,7 @@ setting.type.location.unknown={0} location is unknown setting.type.location.explicit.correct={0} location is defined setting.type.location.explicit.incorrect={0} location is incorrect settings.label.select.project={0} project: +settings.label.project.format=Project format: settings.label.use.auto.import=Use auto-import settings.label.create.empty.content.root.directories=Create directories for empty content roots automatically settings.title.linked.projects=Linked {0} projects diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalModuleBuilder.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalModuleBuilder.java index 052041c5e454..d3084e0ffae7 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalModuleBuilder.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/AbstractExternalModuleBuilder.java @@ -15,29 +15,15 @@ */ package com.intellij.openapi.externalSystem.service.project.wizard; -import com.intellij.ide.fileTemplates.FileTemplate; -import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.externalSystem.model.ProjectSystemId; -import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings; import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; import com.intellij.openapi.externalSystem.util.ExternalSystemBundle; import com.intellij.openapi.externalSystem.util.ExternalSystemUiUtil; -import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.util.io.FileUtilRt; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.io.File; -import java.io.IOException; /** * @author Denis Zhdanov @@ -47,13 +33,12 @@ public abstract class AbstractExternalModuleBuildernull as an indication that no external system config file has been created - */ - @Nullable - protected abstract VirtualFile getExternalProjectConfigFile(@NotNull VirtualFile contentRootDir); - - @Nullable - protected abstract String getTemplateConfigName(@NotNull S settings); } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/SelectExternalProjectStep.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/SelectExternalProjectStep.java index 1a1cbf3f6182..218f7435e10c 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/SelectExternalProjectStep.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/wizard/SelectExternalProjectStep.java @@ -57,6 +57,9 @@ public class SelectExternalProjectStep extends AbstractImportFromExternalSystemW @Override public boolean validate() throws ConfigurationException { myControl.apply(); + if (myControl.getProjectFormatPanel() != null) { + myControl.getProjectFormatPanel().updateData(getWizardContext()); + } AbstractExternalProjectImportBuilder builder = getBuilder(); if (builder == null) { return false; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java index f5931ecedcdc..5dcb5ef71e3b 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java @@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.TextComponentAccessor; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.projectImport.ProjectFormatPanel; import com.intellij.ui.HideableTitledPanel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -53,6 +54,7 @@ public abstract class AbstractImportFromExternalSystemControl< @NotNull private final PaintAwarePanel myComponent = new PaintAwarePanel(new GridBagLayout()); @NotNull private final TextFieldWithBrowseButton myLinkedProjectPathField = new TextFieldWithBrowseButton(); @Nullable private final HideableTitledPanel hideableSystemSettingsPanel; + @Nullable private final ProjectFormatPanel myProjectFormatPanel; @NotNull private final ExternalSystemSettingsControl myProjectSettingsControl; @NotNull private final ProjectSystemId myExternalSystemId; @@ -60,10 +62,18 @@ public abstract class AbstractImportFromExternalSystemControl< @Nullable Project myCurrentProject; - @SuppressWarnings("AbstractMethodCallInConstructor") protected AbstractImportFromExternalSystemControl(@NotNull ProjectSystemId externalSystemId, @NotNull SystemSettings systemSettings, @NotNull ProjectSettings projectSettings) + { + this(externalSystemId, systemSettings, projectSettings, false); + } + + @SuppressWarnings("AbstractMethodCallInConstructor") + protected AbstractImportFromExternalSystemControl(@NotNull ProjectSystemId externalSystemId, + @NotNull SystemSettings systemSettings, + @NotNull ProjectSettings projectSettings, + boolean showProjectFormatPanel) { myExternalSystemId = externalSystemId; mySystemSettings = systemSettings; @@ -104,6 +114,16 @@ public abstract class AbstractImportFromExternalSystemControl< myComponent.add(linkedProjectPathLabel, ExternalSystemUiUtil.getLabelConstraints(0)); myComponent.add(myLinkedProjectPathField, ExternalSystemUiUtil.getFillLineConstraints(0)); myProjectSettingsControl.fillUi(myComponent, 0); + + if(showProjectFormatPanel) { + myProjectFormatPanel = new ProjectFormatPanel(); + JLabel myProjectFormatLabel = new JLabel(ExternalSystemBundle.message("settings.label.project.format")); + myComponent.add(myProjectFormatLabel, ExternalSystemUiUtil.getLabelConstraints(0)); + myComponent.add(myProjectFormatPanel.getStorageFormatComboBox(), ExternalSystemUiUtil.getFillLineConstraints(0)); + } else { + myProjectFormatPanel = null; + } + if (mySystemSettingsControl != null) { final PaintAwarePanel mySystemSettingsControlPanel = new PaintAwarePanel(); mySystemSettingsControl.fillUi(mySystemSettingsControlPanel, 0); @@ -224,4 +244,9 @@ public abstract class AbstractImportFromExternalSystemControl< mySystemSettingsControl.apply(mySystemSettings); } } + + @Nullable + public ProjectFormatPanel getProjectFormatPanel() { + return myProjectFormatPanel; + } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/ExternalSystemConfigLocator.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/ExternalSystemConfigLocator.java index 34b08b477688..241347348f26 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/ExternalSystemConfigLocator.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/ExternalSystemConfigLocator.java @@ -2,10 +2,13 @@ package com.intellij.openapi.externalSystem.service.settings; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + /** * @author Denis Zhdanov * @since 7/16/13 3:36 PM @@ -27,4 +30,13 @@ public interface ExternalSystemConfigLocator { */ @Nullable VirtualFile adjust(@NotNull VirtualFile configPath); + + /** + * Returns all configuration files used by external system to build the project. + * + * @param externalProjectSettings external system project settings + * @return external system project config files + */ + @NotNull + List findAll(@NotNull ExternalProjectSettings externalProjectSettings); } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java index e828a42d8274..245372314fc6 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java @@ -290,8 +290,8 @@ public class ExternalSystemUtil { Set toRefresh = ContainerUtilRt.newHashSet(); for (ExternalProjectSettings setting : projectsSettings) { Long oldModificationStamp = modificationStamps.get(setting.getExternalProjectPath()); - long currentModificationStamp = getTimeStamp(setting.getExternalProjectPath(), externalSystemId); - if (force || currentModificationStamp < 0 || oldModificationStamp == null || oldModificationStamp < currentModificationStamp) { + long currentModificationStamp = getTimeStamp(setting, externalSystemId); + if (force || oldModificationStamp == null || oldModificationStamp < currentModificationStamp) { toRefresh.add(setting.getExternalProjectPath()); } } @@ -304,21 +304,17 @@ public class ExternalSystemUtil { } } - private static long getTimeStamp(@NotNull String path, @NotNull ProjectSystemId externalSystemId) { - VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(path)); - if (vFile == null) { - return -1; - } + private static long getTimeStamp(@NotNull ExternalProjectSettings externalProjectSettings, @NotNull ProjectSystemId externalSystemId) { + long timeStamp = 0; for (ExternalSystemConfigLocator locator : ExternalSystemConfigLocator.EP_NAME.getExtensions()) { if (!externalSystemId.equals(locator.getTargetExternalSystemId())) { continue; } - VirtualFile adjusted = locator.adjust(vFile); - if (adjusted != null) { - vFile = adjusted; + for (VirtualFile virtualFile : locator.findAll(externalProjectSettings)) { + timeStamp += virtualFile.getTimeStamp(); } } - return vFile.getTimeStamp(); + return timeStamp; } /** @@ -469,15 +465,12 @@ public class ExternalSystemUtil { = new ExternalSystemResolveProjectTask(externalSystemId, project, externalProjectPath, isPreviewMode); task.execute(indicator, ExternalSystemTaskNotificationListener.EP_NAME.getExtensions()); + if(project.isDisposed()) return; + final Throwable error = task.getError(); if (error == null) { ExternalSystemManager manager = ExternalSystemApiUtil.getManager(externalSystemId); assert manager != null; - long stamp = getTimeStamp(externalProjectPath, externalSystemId); - if (stamp > 0) { - if(project.isDisposed()) return; - manager.getLocalSettingsProvider().fun(project).getExternalConfigModificationStamps().put(externalProjectPath, stamp); - } DataNode externalProject = task.getExternalProject(); if(externalProject != null) { @@ -491,6 +484,11 @@ public class ExternalSystemUtil { ExternalProjectSettings linkedProjectSettings = manager.getSettingsProvider().fun(project).getLinkedProjectSettings(projectPath); if (linkedProjectSettings != null) { linkedProjectSettings.setModules(externalModulePaths); + + long stamp = getTimeStamp(linkedProjectSettings, externalSystemId); + if (stamp > 0) { + manager.getLocalSettingsProvider().fun(project).getExternalConfigModificationStamps().put(externalProjectPath, stamp); + } } } @@ -504,8 +502,7 @@ public class ExternalSystemUtil { String message = ExternalSystemApiUtil.buildErrorMessage(error); if (StringUtil.isEmpty(message)) { message = String.format( - "Can't resolve %s project at '%s'. Reason: %s", - externalSystemId.getReadableName(), externalProjectPath, message + "Can't resolve %s project at '%s'. Reason: %s", externalSystemId.getReadableName(), externalProjectPath, message ); } diff --git a/plugins/gradle/resources/fileTemplates/internal/Gradle Build Script with wrapper.gradle.ft b/plugins/gradle/resources/fileTemplates/internal/Gradle Build Script with wrapper.gradle.ft index 6199e791db69..170d1acfc457 100644 --- a/plugins/gradle/resources/fileTemplates/internal/Gradle Build Script with wrapper.gradle.ft +++ b/plugins/gradle/resources/fileTemplates/internal/Gradle Build Script with wrapper.gradle.ft @@ -4,8 +4,8 @@ sourceCompatibility = 1.5 version = '1.0' task wrapper(type: Wrapper) { - gradleVersion = '1.8' - distributionUrl = 'http://services.gradle.org/distributions/gradle-1.8-all.zip' + gradleVersion = '1.9' + distributionUrl = 'http://services.gradle.org/distributions/gradle-1.9-all.zip' } repositories { diff --git a/plugins/gradle/resources/fileTemplates/internal/Gradle Settings merge.gradle.ft b/plugins/gradle/resources/fileTemplates/internal/Gradle Settings merge.gradle.ft new file mode 100644 index 000000000000..73f1b4e61a05 --- /dev/null +++ b/plugins/gradle/resources/fileTemplates/internal/Gradle Settings merge.gradle.ft @@ -0,0 +1,6 @@ +#if (${CONTENT} && ${CONTENT} != "")${CONTENT}#end +#if (${MODULE_DIR_NAME} && ${MODULE_DIR_NAME} != "")include '${MODULE_DIR_NAME}' +#if (${MODULE_NAME} && ${MODULE_NAME} != "" && ${MODULE_DIR_NAME} != ${MODULE_NAME})rootProject.children.find { it.name == '${MODULE_DIR_NAME}' }.name = '${MODULE_NAME}' +#end +#end + diff --git a/plugins/gradle/resources/fileTemplates/internal/Gradle Settings.gradle.ft b/plugins/gradle/resources/fileTemplates/internal/Gradle Settings.gradle.ft new file mode 100644 index 000000000000..9fbc0dee9bbd --- /dev/null +++ b/plugins/gradle/resources/fileTemplates/internal/Gradle Settings.gradle.ft @@ -0,0 +1,11 @@ +#if (${PROJECT_NAME} && ${PROJECT_NAME} != "") +#if (((!${MODULE_DIR_NAME} || ${MODULE_DIR_NAME} == "")) && (${MODULE_NAME} && ${MODULE_NAME} != ""))rootProject.name = '${MODULE_NAME}' +#elseif(true)rootProject.name = '${PROJECT_NAME}' +#end +#end +#if (${MODULE_DIR_NAME} && ${MODULE_DIR_NAME} != "") +include '${MODULE_DIR_NAME}' +#if (${MODULE_NAME} && ${MODULE_NAME} != "" && ${MODULE_DIR_NAME} != ${MODULE_NAME})rootProject.children.find { it.name == '${MODULE_DIR_NAME}' }.name = '${MODULE_NAME}' +#end +#end + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleModuleBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleModuleBuilder.java index 36922d3806f9..204b3bd73d0c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleModuleBuilder.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/wizard/GradleModuleBuilder.java @@ -15,19 +15,34 @@ */ package org.jetbrains.plugins.gradle.service.project.wizard; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.ide.util.projectWizard.ModuleWizardStep; import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.externalSystem.service.project.wizard.AbstractExternalModuleBuilder; import com.intellij.openapi.externalSystem.service.project.wizard.ExternalModuleSettingsStep; -import com.intellij.openapi.module.JavaModuleType; -import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.module.StdModuleTypes; +import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings; +import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; +import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; +import com.intellij.openapi.externalSystem.util.ExternalSystemUtil; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.*; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JavaSdkType; import com.intellij.openapi.projectRoots.SdkTypeId; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.service.settings.GradleProjectSettingsControl; @@ -36,6 +51,8 @@ import org.jetbrains.plugins.gradle.settings.GradleProjectSettings; import org.jetbrains.plugins.gradle.util.GradleConstants; import java.io.File; +import java.io.IOException; +import java.util.Map; /** * @author Denis Zhdanov @@ -43,35 +60,68 @@ import java.io.File; */ public class GradleModuleBuilder extends AbstractExternalModuleBuilder { + private static final Logger LOG = Logger.getInstance(GradleModuleBuilder.class); + + private static final String TEMPLATE_GRADLE_SETTINGS = "Gradle Settings.gradle"; + private static final String TEMPLATE_GRADLE_SETTINGS_MERGE = "Gradle Settings merge.gradle"; + private static final String TEMPLATE_GRADLE_BUILD_WITH_WRAPPER = "Gradle Build Script with wrapper.gradle"; + private static final String DEFAULT_TEMPLATE_GRADLE_BUILD = "Gradle Build Script.gradle"; + + private static final String TEMPLATE_ATTRIBUTE_PROJECT_NAME = "PROJECT_NAME"; + private static final String TEMPLATE_ATTRIBUTE_MODULE_DIR_NAME = "MODULE_DIR_NAME"; + private static final String TEMPLATE_ATTRIBUTE_MODULE_NAME = "MODULE_NAME"; + + private @NotNull WizardContext myWizardContext; + public GradleModuleBuilder() { super(GradleConstants.SYSTEM_ID, new GradleProjectSettings()); } - @Nullable @Override - protected VirtualFile getExternalProjectConfigFile(@NotNull VirtualFile contentRootDir) { - File gradleScript = new File(contentRootDir.getPath(), GradleConstants.DEFAULT_SCRIPT_NAME); - FileUtilRt.createIfNotExists(gradleScript); - return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(gradleScript); - } + public void setupRootModel(final ModifiableRootModel modifiableRootModel) throws ConfigurationException { + String contentEntryPath = getContentEntryPath(); + if (StringUtil.isEmpty(contentEntryPath)) { + return; + } + File contentRootDir = new File(contentEntryPath); + FileUtilRt.createDirectory(contentRootDir); + LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + VirtualFile modelContentRootDir = fileSystem.refreshAndFindFileByIoFile(contentRootDir); + if (modelContentRootDir == null) { + return; + } - @Nullable - @Override - protected String getTemplateConfigName(@NotNull GradleProjectSettings settings) { - final String templateName; - if (settings.getDistributionType() == DistributionType.WRAPPED) { - templateName = "Gradle Build Script with wrapper.gradle"; + modifiableRootModel.addContentEntry(modelContentRootDir); + modifiableRootModel.inheritSdk(); + + final Project project = modifiableRootModel.getProject(); + + setupGradleBuildFile(modelContentRootDir); + setupGradleSettingsFile(modelContentRootDir, modifiableRootModel); + + if (myWizardContext.isCreatingNewProject()) { + String externalProjectPath = FileUtil.toCanonicalPath(project.getBasePath()); + getExternalProjectSettings().setExternalProjectPath(externalProjectPath); + AbstractExternalSystemSettings settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID); + //noinspection unchecked + settings.linkProject(getExternalProjectSettings()); } else { - templateName = "Gradle Build Script.gradle"; + FileDocumentManager.getInstance().saveAllDocuments(); + ExternalSystemUtil.refreshProjects(project, GradleConstants.SYSTEM_ID, false); } - return templateName; } @Override public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) { - final GradleProjectSettingsControl settingsControl = new GradleProjectSettingsControl(getExternalProjectSettings()); - return new ModuleWizardStep[]{new ExternalModuleSettingsStep(this, settingsControl)}; + myWizardContext = wizardContext; + if (myWizardContext.isCreatingNewProject()) { + final GradleProjectSettingsControl settingsControl = new GradleProjectSettingsControl(getExternalProjectSettings()); + return new ModuleWizardStep[]{new ExternalModuleSettingsStep(this, settingsControl)}; + } + else { + return ModuleWizardStep.EMPTY_ARRAY; + } } @Override @@ -88,4 +138,111 @@ public class GradleModuleBuilder extends AbstractExternalModuleBuilder attributes = ContainerUtil.newHashMap(); + final String projectName = model.getProject().getName(); + attributes.put(TEMPLATE_ATTRIBUTE_PROJECT_NAME, projectName); + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_DIR_NAME, moduleDirName); + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_NAME, model.getModule().getName()); + saveFile(file, TEMPLATE_GRADLE_SETTINGS, attributes); + } + else { + Map moduleMap = ContainerUtil.newHashMap(); + for (Module module : ModuleManager.getInstance(model.getProject()).getModules()) { + for (ContentEntry contentEntry : model.getContentEntries()) { + if (contentEntry.getFile() != null) { + moduleMap.put(contentEntry.getFile().getPath(), module); + } + } + } + + VirtualFile virtualFile = modelContentRootDir; + Module module = null; + while (virtualFile != null && module == null) { + module = moduleMap.get(virtualFile.getPath()); + virtualFile = virtualFile.getParent(); + } + + if (module != null) { + String rootProjectPath = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY); + + if (!StringUtil.isEmpty(rootProjectPath)) { + VirtualFile rootProjectFile = VfsUtil.findFileByIoFile(new File(rootProjectPath), true); + if (rootProjectFile == null) return null; + + final String moduleDirName = VfsUtilCore.getRelativePath(modelContentRootDir, rootProjectFile, '/'); + file = getExternalProjectConfigFile(rootProjectPath, GradleConstants.SETTINGS_FILE_NAME); + if (file == null) return null; + + Map attributes = ContainerUtil.newHashMap(); + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_DIR_NAME, moduleDirName); + attributes.put(TEMPLATE_ATTRIBUTE_MODULE_NAME, model.getModule().getName()); + appendToFile(file, TEMPLATE_GRADLE_SETTINGS_MERGE, attributes); + } + } + } + return file; + } + + private static void saveFile(@NotNull VirtualFile file, @NotNull String templateName, @Nullable Map templateAttributes) + throws ConfigurationException { + FileTemplateManager manager = FileTemplateManager.getInstance(); + FileTemplate template = manager.getInternalTemplate(templateName); + try { + VfsUtil.saveText(file, templateAttributes != null ? template.getText(templateAttributes) : template.getText()); + } + catch (IOException e) { + LOG.warn(String.format("Unexpected exception on applying template %s config", GradleConstants.SYSTEM_ID.getReadableName()), e); + throw new ConfigurationException( + e.getMessage(), String.format("Can't apply %s template config text", GradleConstants.SYSTEM_ID.getReadableName()) + ); + } + } + + private static void appendToFile(@NotNull VirtualFile file, @NotNull String templateName, @Nullable Map templateAttributes) + throws ConfigurationException { + FileTemplateManager manager = FileTemplateManager.getInstance(); + FileTemplate template = manager.getInternalTemplate(templateName); + try { + VfsUtil.saveText(file, VfsUtilCore.loadText(file) + + (templateAttributes != null ? template.getText(templateAttributes) : template.getText())); + } + catch (IOException e) { + LOG.warn(String.format("Unexpected exception on appending template %s config", GradleConstants.SYSTEM_ID.getReadableName()), e); + throw new ConfigurationException( + e.getMessage(), String.format("Can't append %s template config text", GradleConstants.SYSTEM_ID.getReadableName()) + ); + } + } + + + @Nullable + private static VirtualFile getExternalProjectConfigFile(@NotNull String parent, @NotNull String fileName) { + File file = new File(parent, fileName); + FileUtilRt.createIfNotExists(file); + return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file); + } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleConfigLocator.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleConfigLocator.java index 60c387d435c7..44559316bbbb 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleConfigLocator.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleConfigLocator.java @@ -2,13 +2,17 @@ package org.jetbrains.plugins.gradle.service.settings; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.service.settings.ExternalSystemConfigLocator; +import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ContainerUtil; import org.gradle.tooling.GradleConnector; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.util.GradleConstants; import java.io.File; +import java.util.List; /** * We store not gradle config file but its parent dir path instead. That is implied by gradle design @@ -50,4 +54,22 @@ public class GradleConfigLocator implements ExternalSystemConfigLocator { } return null; } + + @NotNull + @Override + public List findAll(@NotNull ExternalProjectSettings externalProjectSettings) { + List list = ContainerUtil.newArrayList(); + for (String path : externalProjectSettings.getModules()) { + VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(path)); + if (vFile != null) { + for (VirtualFile child : vFile.getChildren()) { + String name = child.getName(); + if (!child.isDirectory() && name.endsWith(GradleConstants.EXTENSION)) { + list.add(child); + } + } + } + } + return list; + } }