@Override public void importData( @NotNull Collection<DataNode<ProjectData>> toImport, @Nullable ProjectData projectData, @NotNull final Project project, @NotNull IdeModifiableModelsProvider modelsProvider) { // root project can be marked as ignored if (toImport.isEmpty()) return; if (toImport.size() != 1) { throw new IllegalArgumentException( String.format( "Expected to get a single project but got %d: %s", toImport.size(), toImport)); } DataNode<ProjectData> node = toImport.iterator().next(); assert projectData == node.getData(); if (!ExternalSystemApiUtil.isOneToOneMapping(project, node)) { return; } if (!project.getName().equals(projectData.getInternalName())) { renameProject(projectData.getInternalName(), projectData.getOwner(), project); } }
/** * Allows to answer if given ide project has 1-1 mapping with the given external project, i.e. the * ide project has been imported from external system and no other external projects have been * added. * * <p>This might be necessary in a situation when project-level setting is changed (e.g. project * name). We don't want to rename ide project if it doesn't completely corresponds to the given * ide project then. * * @param ideProject target ide project * @param externalProject target external project * @return <code>true</code> if given ide project has 1-1 mapping to the given external project; * <code>false</code> otherwise */ public static boolean isOneToOneMapping( @NotNull Project ideProject, @NotNull DataNode<ProjectData> externalProject) { String linkedExternalProjectPath = null; for (ExternalSystemManager<?, ?, ?, ?, ?> manager : ExternalSystemApiUtil.getAllManagers()) { ProjectSystemId externalSystemId = manager.getSystemId(); AbstractExternalSystemSettings systemSettings = ExternalSystemApiUtil.getSettings(ideProject, externalSystemId); Collection projectsSettings = systemSettings.getLinkedProjectsSettings(); int linkedProjectsNumber = projectsSettings.size(); if (linkedProjectsNumber > 1) { // More than one external project of the same external system type is linked to the given // ide project. return false; } else if (linkedProjectsNumber == 1) { if (linkedExternalProjectPath == null) { // More than one external project of different external system types is linked to the // current ide project. linkedExternalProjectPath = ((ExternalProjectSettings) projectsSettings.iterator().next()) .getExternalProjectPath(); } else { return false; } } } ProjectData projectData = externalProject.getData(); if (linkedExternalProjectPath != null && !linkedExternalProjectPath.equals(projectData.getLinkedExternalProjectPath())) { // New external project is being linked. return false; } Set<String> externalModulePaths = ContainerUtilRt.newHashSet(); for (DataNode<ModuleData> moduleNode : ExternalSystemApiUtil.findAll(externalProject, ProjectKeys.MODULE)) { externalModulePaths.add(moduleNode.getData().getLinkedExternalProjectPath()); } externalModulePaths.remove(linkedExternalProjectPath); PlatformFacade platformFacade = ServiceManager.getService(PlatformFacade.class); for (Module module : platformFacade.getModules(ideProject)) { String path = module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY); if (!StringUtil.isEmpty(path) && !externalModulePaths.remove(path)) { return false; } } return externalModulePaths.isEmpty(); }
@Override public void actionPerformed(AnActionEvent e) { final Project project = getProject(e); final ProjectSystemId projectSystemId = getSystemId(e); final List<ExternalSystemNode> selectedNodes = ExternalSystemDataKeys.SELECTED_NODES.getData(e.getDataContext()); final ExternalProjectInfo projectInfo; final ExternalSystemNode<?> externalSystemNode = ContainerUtil.getFirstItem(selectedNodes); if (externalSystemNode == null) { projectInfo = ContainerUtil.getFirstItem( ProjectDataManager.getInstance().getExternalProjectsData(project, projectSystemId)); } else { final ProjectNode projectNode = externalSystemNode instanceof ProjectNode ? (ProjectNode) externalSystemNode : externalSystemNode.findParent(ProjectNode.class); assert projectNode != null; final ProjectData projectData = projectNode.getData(); assert projectData != null; projectInfo = ProjectDataManager.getInstance() .getExternalProjectData( project, projectSystemId, projectData.getLinkedExternalProjectPath()); } final ExternalProjectDataSelectorDialog dialog; if (projectInfo != null) { dialog = new ExternalProjectDataSelectorDialog( project, projectInfo, externalSystemNode != null ? externalSystemNode.getData() : null); dialog.showAndGet(); } }
@NotNull private DataNode<ProjectData> doResolveProjectInfo( @NotNull final ProjectResolverContext resolverCtx, @NotNull final GradleProjectResolverExtension projectResolverChain) throws IllegalArgumentException, IllegalStateException { final ProjectImportAction projectImportAction = new ProjectImportAction(resolverCtx.isPreviewMode()); // inject ProjectResolverContext into gradle project resolver extensions // collect extra JVM arguments provided by gradle project resolver extensions // and register classes of extra gradle project models required for extensions (e.g. // com.android.builder.model.AndroidProject) final List<KeyValue<String, String>> extraJvmArgs = new ArrayList<KeyValue<String, String>>(); for (GradleProjectResolverExtension resolverExtension = projectResolverChain; resolverExtension != null; resolverExtension = resolverExtension.getNext()) { resolverExtension.setProjectResolverContext(resolverCtx); projectImportAction.addExtraProjectModelClasses( resolverExtension.getExtraProjectModelClasses()); extraJvmArgs.addAll(resolverExtension.getExtraJvmArgs()); } final ParametersList parametersList = new ParametersList(); for (KeyValue<String, String> jvmArg : extraJvmArgs) { parametersList.addProperty(jvmArg.getKey(), jvmArg.getValue()); } BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = resolverCtx.getConnection().action(projectImportAction); GradleExecutionHelper.prepare( buildActionExecutor, resolverCtx.getExternalSystemTaskId(), resolverCtx.getSettings(), resolverCtx.getListener(), parametersList.getParameters(), resolverCtx.getConnection()); // TODO [vlad] remove the check if (GradleEnvironment.USE_ENHANCED_TOOLING_API) { GradleExecutionHelper.setInitScript(buildActionExecutor); } ProjectImportAction.AllModels allModels; try { allModels = buildActionExecutor.run(); if (allModels == null) { throw new IllegalStateException( "Unable to get project model for the project: " + resolverCtx.getProjectPath()); } } catch (UnsupportedVersionException unsupportedVersionException) { // Old gradle distribution version used (before ver. 1.8) // fallback to use ModelBuilder gradle tooling API ModelBuilder<? extends IdeaProject> modelBuilder = myHelper.getModelBuilder( resolverCtx.isPreviewMode() ? BasicIdeaProject.class : IdeaProject.class, resolverCtx.getExternalSystemTaskId(), resolverCtx.getSettings(), resolverCtx.getConnection(), resolverCtx.getListener(), parametersList.getParameters()); final IdeaProject ideaProject = modelBuilder.get(); allModels = new ProjectImportAction.AllModels(ideaProject); } final BuildEnvironment buildEnvironment = getBuildEnvironment(resolverCtx); allModels.setBuildEnvironment(buildEnvironment); resolverCtx.setModels(allModels); // import project data ProjectData projectData = projectResolverChain.createProject(); DataNode<ProjectData> projectDataNode = new DataNode<ProjectData>(ProjectKeys.PROJECT, projectData, null); // import java project data JavaProjectData javaProjectData = projectResolverChain.createJavaProjectData(); projectDataNode.createChild(JavaProjectData.KEY, javaProjectData); IdeaProject ideaProject = resolverCtx.getModels().getIdeaProject(); DomainObjectSet<? extends IdeaModule> gradleModules = ideaProject.getModules(); if (gradleModules == null || gradleModules.isEmpty()) { throw new IllegalStateException("No modules found for the target project: " + ideaProject); } final Map<String, Pair<DataNode<ModuleData>, IdeaModule>> moduleMap = ContainerUtilRt.newHashMap(); // import modules data for (IdeaModule gradleModule : gradleModules) { if (gradleModule == null) { continue; } final String moduleName = gradleModule.getName(); if (moduleName == null) { throw new IllegalStateException("Module with undefined name detected: " + gradleModule); } ModuleData moduleData = projectResolverChain.createModule(gradleModule, projectData); Pair<DataNode<ModuleData>, IdeaModule> previouslyParsedModule = moduleMap.get(moduleName); if (previouslyParsedModule != null) { throw new IllegalStateException( String.format( "Modules with duplicate name (%s) detected: '%s' and '%s'", moduleName, moduleData, previouslyParsedModule)); } DataNode<ModuleData> moduleDataNode = projectDataNode.createChild(ProjectKeys.MODULE, moduleData); moduleMap.put( moduleName, new Pair<DataNode<ModuleData>, IdeaModule>(moduleDataNode, gradleModule)); } // populate modules nodes final List<TaskData> allTasks = ContainerUtil.newArrayList(); for (final Pair<DataNode<ModuleData>, IdeaModule> pair : moduleMap.values()) { final DataNode<ModuleData> moduleDataNode = pair.first; final IdeaModule ideaModule = pair.second; projectResolverChain.populateModuleExtraModels(ideaModule, moduleDataNode); projectResolverChain.populateModuleContentRoots(ideaModule, moduleDataNode); projectResolverChain.populateModuleCompileOutputSettings(ideaModule, moduleDataNode); projectResolverChain.populateModuleDependencies(ideaModule, moduleDataNode, projectDataNode); final Collection<TaskData> moduleTasks = projectResolverChain.populateModuleTasks(ideaModule, moduleDataNode, projectDataNode); allTasks.addAll(moduleTasks); } // populate root project tasks final Collection<TaskData> rootProjectTaskCandidates = projectResolverChain.filterRootProjectTasks(allTasks); Set<Pair<String /* task name */, String /* task description */>> rootProjectTaskCandidatesMap = ContainerUtilRt.newHashSet(); for (final TaskData taskData : rootProjectTaskCandidates) { rootProjectTaskCandidatesMap.add(Pair.create(taskData.getName(), taskData.getDescription())); } for (final Pair<String, String> p : rootProjectTaskCandidatesMap) { projectDataNode.createChild( ProjectKeys.TASK, new TaskData( GradleConstants.SYSTEM_ID, p.first, projectData.getLinkedExternalProjectPath(), p.second)); } // ensure unique library names Collection<DataNode<LibraryData>> libraries = ExternalSystemApiUtil.getChildren(projectDataNode, ProjectKeys.LIBRARY); myLibraryNamesMixer.mixNames(libraries); return projectDataNode; }