@NotNull
  @Override
  public Collection<AbstractTreeNode> modify(
      @NotNull final AbstractTreeNode node,
      @NotNull Collection<AbstractTreeNode> collection,
      ViewSettings settings) {
    final Project project = node.getProject();
    if (node instanceof PsiDirectoryNode && project != null) {
      final Module module =
          ModuleUtil.findModuleForPsiElement(((PsiDirectoryNode) node).getValue());
      final Optional<String> buildPath =
          module != null
              ? PantsUtil.getPathFromAddress(
                  module, ExternalSystemConstants.LINKED_PROJECT_PATH_KEY)
              : Optional.empty();
      if (buildPath.isPresent()) {
        final Optional<VirtualFile> buildFile =
            PantsUtil.findFileRelativeToBuildRoot(project, buildPath.get());

        boolean isModuleRoot =
            ArrayUtil.indexOf(
                    ModuleRootManager.getInstance(module).getContentRoots(),
                    ((PsiDirectoryNode) node).getVirtualFile())
                >= 0;
        if (buildFile.isPresent() && isModuleRoot) {
          // Check if there's already a BUILD file in the directory; if so, we don't add another
          final AbstractTreeNode existingBuildFile =
              ContainerUtil.find(
                  collection.iterator(),
                  new Condition<AbstractTreeNode>() {
                    @Override
                    public boolean value(AbstractTreeNode node) {
                      return node instanceof PsiFileNode
                          && buildFile.get().equals(((PsiFileNode) node).getVirtualFile());
                    }
                  });
          if (existingBuildFile == null) {
            final PsiFile buildPsiFile = PsiManager.getInstance(project).findFile(buildFile.get());
            final PsiFileNode buildNode =
                new PsiFileNode(project, buildPsiFile, settings) {
                  @Override
                  protected void updateImpl(PresentationData data) {
                    super.updateImpl(data);
                    data.setIcon(PantsIcons.Icon);
                  }
                };
            final List<AbstractTreeNode> modifiedCollection =
                new ArrayList<AbstractTreeNode>(collection);
            modifiedCollection.add(buildNode);
            return modifiedCollection;
          }
        }
      }
    }
    return collection;
  }
 protected boolean isCourseBasedProject(@NotNull final AbstractTreeNode parent) {
   final Project project = parent.getProject();
   if (project != null) {
     final StudyTaskManager studyTaskManager = StudyTaskManager.getInstance(project);
     if (studyTaskManager.getCourse() == null) {
       return false;
     }
   }
   return true;
 }
コード例 #3
0
  private <T> T getProvider(
      Collection<AbstractTreeNode> selected, ProviderFactory<T> createProvider) {
    if (selected.size() == 0) return null;

    List<SNodeReference> selectedNodePointers = new ArrayList<SNodeReference>();
    Project project = null;
    EditableSModel modelDescriptor = null;

    for (AbstractTreeNode treeNode : selected) {
      if (!(treeNode instanceof MPSPsiElementTreeNode)) return null; // only root nodes please

      MPSPsiRootNode mpsPsiNode = ((MPSPsiElementTreeNode) treeNode).getValue();
      if (!mpsPsiNode.isValid()) return null;

      selectedNodePointers.add(mpsPsiNode.getSNodeReference());

      if (project == null) {
        project = treeNode.getProject();
      } else if (project != treeNode.getProject()) {
        return null; // only same project
      }

      if (modelDescriptor == null) {
        modelDescriptor = getModel(mpsPsiNode);
      } else if (modelDescriptor != getModel(mpsPsiNode)) {
        return null; // only same model
      }
    }
    jetbrains.mps.project.Project mpsProject = ProjectHelper.toMPSProject(project);
    if (mpsProject == null || modelDescriptor == null) return null;

    SModel sModel = modelDescriptor;
    if (sModel == null) return null;

    return createProvider.create(selectedNodePointers, modelDescriptor, sModel, mpsProject);
  }
コード例 #4
0
  private <T> T getModelProvider(
      AbstractTreeNode treeNode, ModelProviderFactory<T> createProvider) {
    if (!(treeNode instanceof MPSPsiModelTreeNode)) return null; // only model

    MPSPsiModel psiModel = ((MPSPsiModelTreeNode) treeNode).getModel();
    if (psiModel == null || !psiModel.isValid()) return null;

    Project project = treeNode.getProject();
    EditableSModel modelDescriptor = getModel(treeNode);

    jetbrains.mps.project.Project mpsProject = ProjectHelper.toMPSProject(project);
    if (mpsProject == null || modelDescriptor == null) return null;

    SModel sModel = modelDescriptor;
    if (sModel == null) return null;

    return createProvider.create(modelDescriptor, sModel, mpsProject);
  }
 @NotNull
 @Override
 public Collection<AbstractTreeNode> modify(
     @NotNull AbstractTreeNode parent,
     @NotNull Collection<AbstractTreeNode> children,
     ViewSettings settings) {
   if (!isCourseBasedProject(parent)) {
     return children;
   }
   Collection<AbstractTreeNode> nodes = new ArrayList<AbstractTreeNode>();
   for (AbstractTreeNode node : children) {
     final Project project = node.getProject();
     if (project != null) {
       if (node.getValue() instanceof PsiDirectory) {
         final PsiDirectory nodeValue = (PsiDirectory) node.getValue();
         if (!nodeValue.getName().contains(EduNames.USER_TESTS)
             && !nodeValue.getName().equals(".idea")) {
           StudyDirectoryNode newNode = new StudyDirectoryNode(project, nodeValue, settings);
           nodes.add(newNode);
         }
       } else {
         if (parent instanceof StudyDirectoryNode && node instanceof PsiFileNode) {
           final PsiFileNode psiFileNode = (PsiFileNode) node;
           final VirtualFile virtualFile = psiFileNode.getVirtualFile();
           if (virtualFile == null) {
             return nodes;
           }
           final TaskFile taskFile = StudyUtils.getTaskFile(project, virtualFile);
           if (taskFile != null) {
             nodes.add(node);
           }
           final String parentName = parent.getName();
           if (parentName != null) {
             if (parentName.equals(EduNames.SANDBOX_DIR)) {
               nodes.add(node);
             }
           }
         }
       }
     }
   }
   return nodes;
 }
コード例 #6
0
 private SNode getNode(AbstractTreeNode treeNode) {
   if (!(treeNode instanceof MPSPsiElementTreeNode)) {
     return null;
   }
   MPSPsiNodeBase psiNode = ((MPSPsiElementTreeNode) treeNode).getValue();
   if (!(psiNode instanceof MPSPsiRealNode)) {
     return null;
   }
   final SNodeReference nodeRef = ((MPSPsiRealNode) psiNode).getSNodeReference();
   final SRepository repository = ProjectHelper.getProjectRepository(treeNode.getProject());
   // TODO remove read action from here once SModelFileTracker stops doing the same (creating read
   // action if not already in one)
   return new ModelComputeRunnable<SNode>(
           new Computable<SNode>() {
             @Override
             public SNode compute() {
               return nodeRef.resolve(repository);
             }
           })
       .runRead(repository.getModelAccess());
 }
コード例 #7
0
  @Override
  public Collection<AbstractTreeNode> modify(
      final AbstractTreeNode treeNode,
      final Collection<AbstractTreeNode> children,
      final ViewSettings settings) {
    final Ref<Collection<AbstractTreeNode>> result =
        new Ref<Collection<AbstractTreeNode>>(children);

    // we're actually in EDT here, but we work with SModels, and various routines assert that we can
    // read, thus read action
    ProjectHelper.getProjectRepository(treeNode.getProject())
        .getModelAccess()
        .runReadAction(
            new Runnable() {
              @Override
              public void run() {
                List<AbstractTreeNode> updatedChildren = null;
                final MPSPsiProvider mpsPsiProvider =
                    MPSPsiProvider.getInstance(treeNode.getProject());

                // if current dir is data source from some model
                FolderDataSource currentDirectoryDataSource = null;

                if (treeNode instanceof PsiDirectoryNode) {
                  // let's see if we have a model built from this dir, e.g. in per-root persistence
                  SModel sModel =
                      SModelFileTracker.getInstance()
                          .findModel(
                              VirtualFileUtils.toIFile(
                                  ((PsiDirectoryNode) treeNode).getVirtualFile()));
                  if (sModel != null) {
                    // adding root nodes (removing their corresponding files' nodes from the tree is
                    // further below)
                    List<MPSPsiElementTreeNode> rootsTreeNodes =
                        new ArrayList<MPSPsiElementTreeNode>();
                    for (SNode root : sModel.getRootNodes()) {
                      rootsTreeNodes.add(
                          new MPSPsiElementTreeNode(
                              treeNode.getProject(),
                              (MPSPsiRootNode) mpsPsiProvider.getPsi(root).getContainingFile(),
                              settings));
                    }
                    if (!rootsTreeNodes.isEmpty() && updatedChildren == null) {
                      updatedChildren = new ArrayList<AbstractTreeNode>(children);
                      updatedChildren.addAll(rootsTreeNodes);
                    }

                    DataSource dataSource = sModel.getSource();
                    if (dataSource instanceof FolderDataSource) {
                      // could be assert as currently SModelFileTracker only tracks FileDataSource
                      // and FolderDataSource
                      currentDirectoryDataSource = (FolderDataSource) dataSource;
                    }
                  }
                } else if (treeNode instanceof MPSPsiModelTreeNode) {
                  MPSPsiModel psiModel = ((MPSPsiModelTreeNode) treeNode).extractPsiFromValue();
                  updatedChildren = new ArrayList<AbstractTreeNode>();
                  for (PsiElement psiElement : psiModel.getChildren()) {
                    updatedChildren.add(
                        new MPSPsiElementTreeNode(
                            treeNode.getProject(), (MPSPsiRootNode) psiElement, settings));
                  }
                }

                for (final AbstractTreeNode child : children) {
                  if (child instanceof PsiFileNode) {
                    VirtualFile vFile = ((PsiFileNode) child).getVirtualFile();
                    if (vFile == null) {
                      continue;
                    }

                    // check if it's a single file model
                    final SModel sModel =
                        SModelFileTracker.getInstance().findModel(VirtualFileUtils.toIFile(vFile));
                    if (sModel != null) {
                      if (updatedChildren == null)
                        updatedChildren = new ArrayList<AbstractTreeNode>(children);
                      int idx = updatedChildren.indexOf(child);
                      updatedChildren.remove(idx);
                      updatedChildren.add(
                          idx,
                          new MPSPsiModelTreeNode(
                              treeNode.getProject(), mpsPsiProvider.getPsi(sModel), settings));
                      continue;
                    }

                    if (currentDirectoryDataSource != null
                        && currentDirectoryDataSource.isIncluded(VirtualFileUtils.toIFile(vFile))) {
                      // it's a file that constitutes a FolderDataSource-backed model, remove it
                      // from the tree (root nodes are shown instead)
                      if (updatedChildren == null)
                        updatedChildren = new ArrayList<AbstractTreeNode>(children);
                      int idx = updatedChildren.indexOf(child);
                      updatedChildren.remove(idx);
                    }

                  } else if (child instanceof PsiDirectoryNode) {
                    // below code only attaches our action to the directory and makes it show added
                    // children - our root nodes

                    final SModel perRootModel =
                        SModelFileTracker.getInstance()
                            .findModel(
                                VirtualFileUtils.toIFile(
                                    ((PsiDirectoryNode) child).getVirtualFile()));
                    if (perRootModel != null) {
                      if (updatedChildren == null)
                        updatedChildren = new ArrayList<AbstractTreeNode>(children);

                      int idx = updatedChildren.indexOf(child);
                      updatedChildren.remove(idx);
                      updatedChildren.add(
                          idx,
                          new PsiDirectoryNode(
                              treeNode.getProject(),
                              ((PsiDirectoryNode) child).getValue(),
                              settings) {
                            @Override
                            public boolean canNavigate() {
                              return true;
                            }

                            @Override
                            public String getNavigateActionText(boolean focusEditor) {
                              return MPSBundle.message("open.model.properties.action");
                            }

                            @Override
                            public void navigate(boolean requestFocus) {
                              MPSPropertiesConfigurable configurable =
                                  new ModelPropertiesConfigurable(
                                      perRootModel, ProjectHelper.toMPSProject(myProject), true);
                              final SingleConfigurableEditor dialog =
                                  new SingleConfigurableEditor(myProject, configurable);
                              configurable.setParentForCallBack(dialog);
                              SwingUtilities.invokeLater(
                                  new Runnable() {
                                    @Override
                                    public void run() {
                                      dialog.show();
                                    }
                                  });
                            }
                          });
                    }
                  }
                }

                if (updatedChildren != null) {
                  result.set(updatedChildren);
                }
              }
            });

    return result.get();
  }
コード例 #8
0
 private Module getIdeaModule(AbstractTreeNode treeNode) {
   VirtualFile modelVFile = getVirtualFile(treeNode);
   if (modelVFile == null) return null;
   return ModuleUtilCore.findModuleForFile(modelVFile, treeNode.getProject());
 }