@Override
  protected void processData(
      @NotNull Collection<DataNode<TaskData>> nodes, @NotNull Project project) {
    if (nodes.isEmpty()) {
      return;
    }
    ProjectSystemId externalSystemId = nodes.iterator().next().getData().getOwner();
    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(externalSystemId);
    assert manager != null;

    ExternalSystemKeymapExtension.updateActions(project, nodes);

    MultiMap<ExternalConfigPathAware, DataNode<TaskData>> grouped =
        ContainerUtil.groupBy(nodes, TASK_HOLDER_RETRIEVAL_STRATEGY);
    Map<String, Collection<ExternalTaskPojo>> data = ContainerUtilRt.newHashMap();
    for (Map.Entry<ExternalConfigPathAware, Collection<DataNode<TaskData>>> entry :
        grouped.entrySet()) {
      data.put(
          entry.getKey().getLinkedExternalProjectPath(),
          ContainerUtilRt.map2List(entry.getValue(), MAPPER));
    }

    AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
    Map<String, Collection<ExternalTaskPojo>> availableTasks =
        ContainerUtilRt.newHashMap(settings.getAvailableTasks());
    availableTasks.putAll(data);
    settings.setAvailableTasks(availableTasks);
  }
  @Override
  protected void processData(
      @NotNull final Collection<DataNode<ModuleData>> nodes, @NotNull Project project) {
    if (nodes.isEmpty()) {
      return;
    }
    ProjectSystemId externalSystemId = nodes.iterator().next().getData().getOwner();
    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(externalSystemId);
    assert manager != null;

    final MultiMap<DataNode<ProjectData>, DataNode<ModuleData>> grouped =
        ExternalSystemApiUtil.groupBy(nodes, ProjectKeys.PROJECT);
    Map<ExternalProjectPojo, Collection<ExternalProjectPojo>> data = ContainerUtilRt.newHashMap();
    for (Map.Entry<DataNode<ProjectData>, Collection<DataNode<ModuleData>>> entry :
        grouped.entrySet()) {
      data.put(
          ExternalProjectPojo.from(entry.getKey().getData()),
          ContainerUtilRt.map2List(entry.getValue(), MAPPER));
    }

    AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
    Set<String> pathsToForget = detectRenamedProjects(data, settings.getAvailableProjects());
    if (!pathsToForget.isEmpty()) {
      settings.forgetExternalProjects(pathsToForget);
    }
    Map<ExternalProjectPojo, Collection<ExternalProjectPojo>> projects =
        ContainerUtilRt.newHashMap(settings.getAvailableProjects());
    projects.putAll(data);
    settings.setAvailableProjects(projects);
  }
 @Nullable
 public static ExternalSystemManager<?, ?, ?, ?, ?> getManager(
     @NotNull ProjectSystemId externalSystemId) {
   for (ExternalSystemManager manager : ExternalSystemManager.EP_NAME.getExtensions()) {
     if (externalSystemId.equals(manager.getSystemId())) {
       return manager;
     }
   }
   return null;
 }
 @SuppressWarnings("unchecked")
 public static <S extends AbstractExternalSystemLocalSettings> S getLocalSettings(
     @NotNull Project project, @NotNull ProjectSystemId externalSystemId)
     throws IllegalArgumentException {
   ExternalSystemManager<?, ?, ?, ?, ?> manager = getManager(externalSystemId);
   if (manager == null) {
     throw new IllegalArgumentException(
         String.format(
             "Can't retrieve local external system settings for id '%s'. Reason: no such external system is registered",
             externalSystemId.getReadableName()));
   }
   return (S) manager.getLocalSettingsProvider().fun(project);
 }
예제 #5
0
  /**
   * 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();
  }
 @SuppressWarnings("unchecked")
 public static <S extends ExternalSystemExecutionSettings> S getExecutionSettings(
     @NotNull Project project,
     @NotNull String linkedProjectPath,
     @NotNull ProjectSystemId externalSystemId)
     throws IllegalArgumentException {
   ExternalSystemManager<?, ?, ?, ?, ?> manager = getManager(externalSystemId);
   if (manager == null) {
     throw new IllegalArgumentException(
         String.format(
             "Can't retrieve external system execution settings for id '%s'. Reason: no such external system is registered",
             externalSystemId.getReadableName()));
   }
   return (S) manager.getExecutionSettingsProvider().fun(Pair.create(project, linkedProjectPath));
 }
  private static List<ProjectSystemId> getSystemIds(AnActionEvent e) {
    final List<ProjectSystemId> systemIds = ContainerUtil.newArrayList();

    final ProjectSystemId externalSystemId =
        ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID.getData(e.getDataContext());
    if (externalSystemId != null) {
      systemIds.add(externalSystemId);
    } else {
      for (ExternalSystemManager manager : ExternalSystemManager.EP_NAME.getExtensions()) {
        systemIds.add(manager.getSystemId());
      }
    }

    return systemIds;
  }
예제 #8
0
  /**
   * Is expected to be called when given task info is about to be executed.
   *
   * <p>Basically, this method updates recent tasks list at the corresponding external system tool
   * window and persists new recent tasks state.
   *
   * @param taskInfo task which is about to be executed
   * @param project target project
   */
  public static void updateRecentTasks(
      @NotNull ExternalTaskExecutionInfo taskInfo, @NotNull Project project) {
    ProjectSystemId externalSystemId = taskInfo.getSettings().getExternalSystemId();
    ExternalSystemRecentTasksList recentTasksList =
        getToolWindowElement(
            ExternalSystemRecentTasksList.class,
            project,
            ExternalSystemDataKeys.RECENT_TASKS_LIST,
            externalSystemId);
    if (recentTasksList == null) {
      return;
    }
    recentTasksList.setFirst(taskInfo);

    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(externalSystemId);
    assert manager != null;
    AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
    settings.setRecentTasks(recentTasksList.getModel().getTasks());
  }
  @Override
  public void importData(
      @NotNull final Collection<DataNode<BuildScriptClasspathData>> toImport,
      @NotNull final Project project,
      boolean synchronous) {
    if (toImport.isEmpty()) {
      return;
    }
    if (!project.isInitialized()) {
      return;
    }

    final GradleInstallationManager gradleInstallationManager =
        ServiceManager.getService(GradleInstallationManager.class);

    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(GradleConstants.SYSTEM_ID);
    assert manager != null;
    AbstractExternalSystemLocalSettings localSettings =
        manager.getLocalSettingsProvider().fun(project);

    //noinspection MismatchedQueryAndUpdateOfCollection
    Map<String /* externalProjectPath */, Set<String>> externalProjectGradleSdkLibs =
        new FactoryMap<String, Set<String>>() {
          @Nullable
          @Override
          protected Set<String> create(String externalProjectPath) {
            GradleProjectSettings settings =
                GradleSettings.getInstance(project).getLinkedProjectSettings(externalProjectPath);
            if (settings == null || settings.getDistributionType() == null) return null;

            final Set<String> gradleSdkLibraries = ContainerUtil.newLinkedHashSet();
            File gradleHome =
                gradleInstallationManager.getGradleHome(
                    settings.getDistributionType(), externalProjectPath, settings.getGradleHome());
            if (gradleHome != null && gradleHome.isDirectory()) {

              final Collection<File> libraries =
                  gradleInstallationManager.getClassRoots(project, externalProjectPath);
              if (libraries != null) {
                for (File library : libraries) {
                  gradleSdkLibraries.add(FileUtil.toCanonicalPath(library.getPath()));
                }
              }
            }
            return gradleSdkLibraries;
          }
        };

    for (final DataNode<BuildScriptClasspathData> node : toImport) {
      if (GradleConstants.SYSTEM_ID.equals(node.getData().getOwner())) {

        DataNode<ProjectData> projectDataNode =
            ExternalSystemApiUtil.findParent(node, ProjectKeys.PROJECT);
        assert projectDataNode != null;

        String linkedExternalProjectPath = projectDataNode.getData().getLinkedExternalProjectPath();
        DataNode<ModuleData> moduleDataNode =
            ExternalSystemApiUtil.findParent(node, ProjectKeys.MODULE);
        if (moduleDataNode == null) continue;

        String externalModulePath = moduleDataNode.getData().getLinkedExternalProjectPath();
        GradleProjectSettings settings =
            GradleSettings.getInstance(project).getLinkedProjectSettings(linkedExternalProjectPath);
        if (settings == null || settings.getDistributionType() == null) continue;

        final Set<String> buildClasspath = ContainerUtil.newLinkedHashSet();
        BuildScriptClasspathData buildScriptClasspathData = node.getData();
        for (BuildScriptClasspathData.ClasspathEntry classpathEntry :
            buildScriptClasspathData.getClasspathEntries()) {
          for (String path : classpathEntry.getSourcesFile()) {
            buildClasspath.add(FileUtil.toCanonicalPath(path));
          }

          for (String path : classpathEntry.getClassesFile()) {
            buildClasspath.add(FileUtil.toCanonicalPath(path));
          }
        }

        ExternalProjectBuildClasspathPojo projectBuildClasspathPojo =
            localSettings.getProjectBuildClasspath().get(linkedExternalProjectPath);
        if (projectBuildClasspathPojo == null) {
          projectBuildClasspathPojo =
              new ExternalProjectBuildClasspathPojo(
                  moduleDataNode.getData().getExternalName(),
                  ContainerUtil.<String>newArrayList(),
                  ContainerUtil.<String, ExternalModuleBuildClasspathPojo>newHashMap());
          localSettings
              .getProjectBuildClasspath()
              .put(linkedExternalProjectPath, projectBuildClasspathPojo);
        }

        List<String> projectBuildClasspath =
            ContainerUtil.newArrayList(externalProjectGradleSdkLibs.get(linkedExternalProjectPath));
        // add main java root of buildSrc project
        projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/java");
        // add main groovy root of buildSrc project
        projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/groovy");

        projectBuildClasspathPojo.setProjectBuildClasspath(projectBuildClasspath);
        projectBuildClasspathPojo
            .getModulesBuildClasspath()
            .put(
                externalModulePath,
                new ExternalModuleBuildClasspathPojo(
                    externalModulePath, ContainerUtil.newArrayList(buildClasspath)));
      }
    }

    GradleBuildClasspathManager.getInstance(project).reload();
  }
  public ExternalSystemTasksPanel(
      @NotNull Project project,
      @NotNull ProjectSystemId externalSystemId,
      @NotNull NotificationGroup notificationGroup) {
    super(true);
    myExternalSystemId = externalSystemId;
    myNotificationGroup = notificationGroup;
    myProject = project;

    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(externalSystemId);
    assert manager != null;
    AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);

    ExternalSystemRecentTaskListModel recentTasksModel =
        new ExternalSystemRecentTaskListModel(externalSystemId, project);
    recentTasksModel.setTasks(settings.getRecentTasks());
    myRecentTasksList =
        new ExternalSystemRecentTasksList(recentTasksModel, externalSystemId, project) {
          @Override
          protected void processMouseEvent(MouseEvent e) {
            if (e.getClickCount() > 0) {
              mySelectedTaskProvider = myRecentTasksList;
              myAllTasksTree.getSelectionModel().clearSelection();
            }
            super.processMouseEvent(e);
          }
        };

    myAllTasksModel = new ExternalSystemTasksTreeModel(externalSystemId);
    myAllTasksTree =
        new ExternalSystemTasksTree(
            myAllTasksModel, settings.getExpandStates(), project, externalSystemId) {
          @Override
          protected void processMouseEvent(MouseEvent e) {
            if (e.getClickCount() > 0) {
              mySelectedTaskProvider = myAllTasksTree;
              myRecentTasksList.getSelectionModel().clearSelection();
            }
            super.processMouseEvent(e);
          }
        };
    final String actionIdToUseForDoubleClick =
        DefaultRunExecutor.getRunExecutorInstance().getContextActionId();
    myAllTasksTree.addMouseListener(
        new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() >= 2 && !e.isPopupTrigger()) {
              ExternalSystemUiUtil.executeAction(actionIdToUseForDoubleClick, e);
            }
          }
        });
    ExternalSystemUiUtil.apply(settings, myAllTasksModel);
    CustomizationUtil.installPopupHandler(
        myAllTasksTree, TREE_ACTIONS_GROUP_ID, TREE_CONTEXT_MENU_PLACE);

    ActionManager actionManager = ActionManager.getInstance();
    ActionGroup group = (ActionGroup) actionManager.getAction(TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID);
    ActionToolbar toolbar = actionManager.createActionToolbar(TOOL_WINDOW_PLACE, group, true);
    toolbar.setTargetComponent(this);
    setToolbar(toolbar.getComponent());

    JPanel content = new JPanel(new GridBagLayout());
    content.setOpaque(true);
    content.setBackground(UIUtil.getListBackground());
    JComponent recentTasksWithTitle =
        wrap(myRecentTasksList, ExternalSystemBundle.message("tasks.recent.title"));
    content.add(recentTasksWithTitle, ExternalSystemUiUtil.getFillLineConstraints(0));
    JBScrollPane scrollPane = new JBScrollPane(myAllTasksTree);
    scrollPane.setBorder(null);
    JComponent allTasksWithTitle =
        wrap(scrollPane, ExternalSystemBundle.message("tasks.all.title"));
    content.add(
        allTasksWithTitle, ExternalSystemUiUtil.getFillLineConstraints(0).weighty(1).fillCell());
    setContent(content);
  }
  public KeymapGroup createGroup(Condition<AnAction> condition, final Project project) {
    KeymapGroup result =
        KeymapGroupFactory.getInstance()
            .createGroup(
                ExternalSystemBundle.message("external.system.keymap.group"),
                ExternalSystemIcons.TaskGroup);
    if (project == null) return result;

    MultiMap<ProjectSystemId, String> projectToActionsMapping = MultiMap.create();
    for (ExternalSystemManager<?, ?, ?, ?, ?> manager : ExternalSystemApiUtil.getAllManagers()) {
      projectToActionsMapping.putValues(manager.getSystemId(), ContainerUtil.<String>emptyList());
    }

    ActionManager actionManager = ActionManager.getInstance();
    if (actionManager != null) {
      for (String eachId : actionManager.getActionIds(getActionPrefix(project, null))) {
        AnAction eachAction = actionManager.getAction(eachId);

        if (!(eachAction instanceof MyExternalSystemAction)) continue;
        if (condition != null && !condition.value(actionManager.getActionOrStub(eachId))) continue;

        MyExternalSystemAction taskAction = (MyExternalSystemAction) eachAction;
        projectToActionsMapping.putValue(taskAction.getSystemId(), eachId);
      }
    }

    Map<ProjectSystemId, KeymapGroup> keymapGroupMap = ContainerUtil.newHashMap();
    for (ProjectSystemId systemId : projectToActionsMapping.keySet()) {
      if (!keymapGroupMap.containsKey(systemId)) {
        final Icon projectIcon = ExternalSystemUiUtil.getUiAware(systemId).getProjectIcon();
        KeymapGroup group =
            KeymapGroupFactory.getInstance().createGroup(systemId.getReadableName(), projectIcon);
        result.addGroup(group);
        keymapGroupMap.put(systemId, group);
      }
    }

    for (Map.Entry<ProjectSystemId, Collection<String>> each : projectToActionsMapping.entrySet()) {
      Collection<String> tasks = each.getValue();
      final ProjectSystemId systemId = each.getKey();
      final KeymapGroup systemGroup = keymapGroupMap.get(systemId);
      for (String actionId : tasks) {
        systemGroup.addActionId(actionId);
      }
      if (systemGroup instanceof Group) {
        Icon icon =
            SystemInfoRt.isMac ? AllIcons.ToolbarDecorator.Mac.Add : AllIcons.ToolbarDecorator.Add;
        ((Group) systemGroup)
            .addHyperlink(
                new Hyperlink(icon, "Choose a task to assign a shortcut") {
                  @Override
                  public void onClick(MouseEvent e) {
                    SelectExternalTaskDialog dialog =
                        new SelectExternalTaskDialog(systemId, project);
                    if (dialog.showAndGet() && dialog.getResult() != null) {
                      TaskData taskData = dialog.getResult().second;
                      String ownerModuleName = dialog.getResult().first;
                      ExternalSystemTaskAction externalSystemAction =
                          (ExternalSystemTaskAction)
                              getOrRegisterAction(project, ownerModuleName, taskData);

                      ApplicationManager.getApplication()
                          .getMessageBus()
                          .syncPublisher(KeymapListener.CHANGE_TOPIC)
                          .processCurrentKeymapChanged();

                      Settings allSettings =
                          Settings.KEY.getData(
                              DataManager.getInstance().getDataContext(e.getComponent()));
                      KeymapPanel keymapPanel =
                          allSettings != null ? allSettings.find(KeymapPanel.class) : null;
                      if (keymapPanel != null) {
                        // clear actions filter
                        keymapPanel.showOption("");
                        keymapPanel.selectAction(externalSystemAction.myId);
                      }
                    }
                  }
                });
      }
    }

    for (ActionsProvider extension : ActionsProvider.EP_NAME.getExtensions()) {
      KeymapGroup group = extension.createGroup(condition, project);
      if (group != null) {
        result.addGroup(group);
      }
    }

    return result;
  }
예제 #12
0
  /**
   * Asks to refresh all external projects of the target external system linked to the given ide
   * project based on provided spec
   *
   * @param specBuilder import specification builder
   */
  public static void refreshProjects(@NotNull final ImportSpecBuilder specBuilder) {
    ImportSpec spec = specBuilder.build();

    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(spec.getExternalSystemId());
    if (manager == null) {
      return;
    }
    AbstractExternalSystemSettings<?, ?, ?> settings =
        manager.getSettingsProvider().fun(spec.getProject());
    final Collection<? extends ExternalProjectSettings> projectsSettings =
        settings.getLinkedProjectsSettings();
    if (projectsSettings.isEmpty()) {
      return;
    }

    final ProjectDataManager projectDataManager =
        ServiceManager.getService(ProjectDataManager.class);
    final int[] counter = new int[1];

    ExternalProjectRefreshCallback callback =
        new MyMultiExternalProjectRefreshCallback(
            spec.getProject(), projectDataManager, counter, spec.getExternalSystemId());

    Map<String, Long> modificationStamps =
        manager
            .getLocalSettingsProvider()
            .fun(spec.getProject())
            .getExternalConfigModificationStamps();
    Set<String> toRefresh = ContainerUtilRt.newHashSet();
    for (ExternalProjectSettings setting : projectsSettings) {

      // don't refresh project when auto-import is disabled if such behavior needed (e.g. on project
      // opening when auto-import is disabled)
      if (!setting.isUseAutoImport() && spec.isWhenAutoImportEnabled()) continue;

      if (spec.isForceWhenUptodate()) {
        toRefresh.add(setting.getExternalProjectPath());
      } else {
        Long oldModificationStamp = modificationStamps.get(setting.getExternalProjectPath());
        long currentModificationStamp = getTimeStamp(setting, spec.getExternalSystemId());
        if (oldModificationStamp == null || oldModificationStamp < currentModificationStamp) {
          toRefresh.add(setting.getExternalProjectPath());
        }
      }
    }

    if (!toRefresh.isEmpty()) {
      ExternalSystemNotificationManager.getInstance(spec.getProject())
          .clearNotifications(null, NotificationSource.PROJECT_SYNC, spec.getExternalSystemId());

      counter[0] = toRefresh.size();
      for (String path : toRefresh) {
        refreshProject(
            spec.getProject(),
            spec.getExternalSystemId(),
            path,
            callback,
            false,
            spec.getProgressExecutionMode());
      }
    }
  }