summaryrefslogtreecommitdiff
path: root/platform/lang-impl/src/com/intellij/ide/navigationToolbar/DefaultNavBarExtension.java
blob: 9bfd75e0b4f9520e967933f2bbb1cbaed1a39160 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * 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.
 */

/*
 * User: anna
 * Date: 04-Feb-2008
 */
package com.intellij.ide.navigationToolbar;

import com.intellij.analysis.AnalysisScopeBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.InternalModuleType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiFileSystemItemProcessor;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class DefaultNavBarExtension extends AbstractNavBarModelExtension {
  @Override
  @Nullable
  public String getPresentableText(final Object object) {
    if (object instanceof Project) {
      return ((Project)object).getName();
    }
    else if (object instanceof Module) {
      return ((Module)object).getName();
    }
    else if (object instanceof PsiFile) {
      return ((PsiFile)object).getName();
    }
    else if (object instanceof PsiDirectory) {
      return ((PsiDirectory)object).getVirtualFile().getName();
    }
    else if (object instanceof JdkOrderEntry) {
      return ((JdkOrderEntry)object).getJdkName();
    }
    else if (object instanceof LibraryOrderEntry) {
      final String libraryName = ((LibraryOrderEntry)object).getLibraryName();
      return libraryName != null ? libraryName : AnalysisScopeBundle.message("package.dependencies.library.node.text");
    }
    else if (object instanceof ModuleOrderEntry) {
      final ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)object;
      return moduleOrderEntry.getModuleName();
    }
    return null;
  }

  @Override
  public PsiElement adjustElement(final PsiElement psiElement) {
    final PsiFile containingFile = psiElement.getContainingFile();
    if (containingFile != null) return containingFile;
    return psiElement;
  }

  @Override
  public boolean processChildren(final Object object, final Object rootElement, final Processor<Object> processor) {
    if (object instanceof Project) {
      return processChildren((Project)object, processor);
    }
    else if (object instanceof Module) {
      return processChildren((Module)object, processor);
    }
    else if (object instanceof PsiDirectoryContainer) {
      final PsiDirectoryContainer psiPackage = (PsiDirectoryContainer)object;
      final PsiDirectory[] psiDirectories = ApplicationManager.getApplication().runReadAction(
        new Computable<PsiDirectory[]>() {
          @Override
          public PsiDirectory[] compute() {
            return rootElement instanceof Module
                   ? psiPackage.getDirectories(GlobalSearchScope.moduleScope((Module)rootElement))
                   : psiPackage.getDirectories();
          }
        }
      );
      for (PsiDirectory psiDirectory : psiDirectories) {
        if (!processChildren(psiDirectory, rootElement, processor)) return false;
      }
      return true;
    }
    else if (object instanceof PsiDirectory) {
      return processChildren((PsiDirectory)object, rootElement, processor);
    }
    else if (object instanceof PsiFileSystemItem) {
      return processChildren((PsiFileSystemItem)object, processor);
    }
    return true;
  }

  private static boolean processChildren(final Project object, final Processor<Object> processor) {
    return ApplicationManager.getApplication().runReadAction(
      new Computable<Boolean>() {
        @Override
        public Boolean compute() {
          for (Module module : ModuleManager.getInstance(object).getModules()) {
            if (!(ModuleType.get(module) instanceof InternalModuleType) && !processor.process(module)) return false;
          }
          return true;
        }
      }
    );
  }

  private static boolean processChildren(Module module, Processor<Object> processor) {
    final PsiManager psiManager = PsiManager.getInstance(module.getProject());
    ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
    VirtualFile[] roots = moduleRootManager.getContentRoots();
    for (final VirtualFile root : roots) {
      final PsiDirectory psiDirectory = ApplicationManager.getApplication().runReadAction(
        new Computable<PsiDirectory>() {
          @Override
          public PsiDirectory compute() {
            return psiManager.findDirectory(root);
          }
        }
      );
      if (psiDirectory != null) {
        if (!processor.process(psiDirectory)) return false;
      }
    }
    return true;
  }

  private static boolean processChildren(final PsiDirectory object, final Object rootElement, final Processor<Object> processor) {
    return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
      @Override
      public Boolean compute() {
        final ModuleFileIndex moduleFileIndex =
          rootElement instanceof Module ? ModuleRootManager.getInstance((Module)rootElement).getFileIndex() : null;
        final PsiElement[] children = object.getChildren();
        for (PsiElement child : children) {
          if (child != null && child.isValid()) {
            if (moduleFileIndex != null) {
              final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(child);
              if (virtualFile != null && !moduleFileIndex.isInContent(virtualFile)) continue;
            }
            if (!processor.process(child)) return false;
          }
        }
        return true;
      }
    });
  }

  private static boolean processChildren(final PsiFileSystemItem object, final Processor<Object> processor) {
    return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
      @Override
      public Boolean compute() {
        return object.processChildren(new PsiFileSystemItemProcessor() {
          @Override
          public boolean acceptItem(String name, boolean isDirectory) {
            return true;
          }

          @Override
          public boolean execute(@NotNull PsiFileSystemItem element) {
            return processor.process(element);
          }
        });
      }
    });
  }
}