5 package com
.intellij
.ide
.projectView
.impl
.nodes
;
7 import com
.intellij
.ide
.projectView
.ProjectViewNode
;
8 import com
.intellij
.ide
.projectView
.ViewSettings
;
9 import com
.intellij
.ide
.util
.treeView
.AbstractTreeNode
;
10 import com
.intellij
.openapi
.components
.ServiceManager
;
11 import com
.intellij
.openapi
.diagnostic
.Logger
;
12 import com
.intellij
.openapi
.module
.Module
;
13 import com
.intellij
.openapi
.project
.Project
;
14 import com
.intellij
.openapi
.roots
.ModuleFileIndex
;
15 import com
.intellij
.openapi
.roots
.ModuleRootManager
;
16 import com
.intellij
.openapi
.roots
.ProjectFileIndex
;
17 import com
.intellij
.openapi
.roots
.ProjectRootManager
;
18 import com
.intellij
.openapi
.util
.Comparing
;
19 import com
.intellij
.openapi
.vfs
.VirtualFile
;
20 import com
.intellij
.psi
.PsiDirectory
;
21 import com
.intellij
.psi
.PsiElement
;
22 import com
.intellij
.psi
.PsiFile
;
23 import org
.jetbrains
.annotations
.NotNull
;
24 import org
.jetbrains
.annotations
.Nullable
;
26 import java
.util
.ArrayList
;
27 import java
.util
.Collection
;
28 import java
.util
.List
;
30 public class ProjectViewDirectoryHelper
{
31 protected static final Logger LOG
= Logger
.getInstance("#" + ProjectViewDirectoryHelper
.class.getName());
33 private final Project myProject
;
35 public static ProjectViewDirectoryHelper
getInstance(Project project
) {
36 return ServiceManager
.getService(project
, ProjectViewDirectoryHelper
.class);
39 public ProjectViewDirectoryHelper(Project project
) {
43 public Project
getProject() {
48 public String
getLocationString(@NotNull PsiDirectory psiDirectory
, boolean forceLocation
) {
49 final VirtualFile directory
= psiDirectory
.getVirtualFile();
50 final VirtualFile contentRootForFile
= ProjectRootManager
.getInstance(myProject
)
51 .getFileIndex().getContentRootForFile(directory
);
52 if (Comparing
.equal(contentRootForFile
, psiDirectory
)) {
53 return directory
.getPresentableUrl();
60 public boolean isShowFQName(ViewSettings settings
, Object parentValue
, PsiDirectory value
) {
66 public String
getNodeName(ViewSettings settings
, Object parentValue
, PsiDirectory directory
) {
67 return directory
.getName();
70 public boolean skipDirectory(PsiDirectory directory
) {
74 public boolean showFileInLibClasses(VirtualFile vFile
) {
78 public boolean isEmptyMiddleDirectory(PsiDirectory directory
, final boolean strictlyEmpty
) {
82 public boolean canRepresent(Object element
, PsiDirectory directory
) {
83 if (element
instanceof VirtualFile
) {
84 VirtualFile vFile
= (VirtualFile
) element
;
85 return directory
.getVirtualFile() == vFile
;
90 public Collection
<AbstractTreeNode
> getDirectoryChildren(final PsiDirectory psiDirectory
,
91 final ViewSettings settings
,
92 final boolean withSubDirectories
) {
93 final List
<AbstractTreeNode
> children
= new ArrayList
<AbstractTreeNode
>();
94 final Project project
= psiDirectory
.getProject();
95 final ProjectFileIndex fileIndex
= ProjectRootManager
.getInstance(project
).getFileIndex();
96 final Module module
= fileIndex
.getModuleForFile(psiDirectory
.getVirtualFile());
97 final ModuleFileIndex moduleFileIndex
= module
== null ?
null : ModuleRootManager
.getInstance(module
).getFileIndex();
98 if (!settings
.isFlattenPackages() || skipDirectory(psiDirectory
)) {
99 processPsiDirectoryChildren(psiDirectory
, psiDirectory
.getChildren(), children
, fileIndex
, moduleFileIndex
, settings
,
102 else { // source directory in "flatten packages" mode
103 final PsiDirectory parentDir
= psiDirectory
.getParentDirectory();
104 if (parentDir
== null || skipDirectory(parentDir
) /*|| !rootDirectoryFound(parentDir)*/ && withSubDirectories
) {
105 addAllSubpackages(children
, psiDirectory
, moduleFileIndex
, settings
);
107 PsiDirectory
[] subdirs
= psiDirectory
.getSubdirectories();
108 for (PsiDirectory subdir
: subdirs
) {
109 if (!skipDirectory(subdir
)) {
112 if (moduleFileIndex
!= null) {
113 if (!moduleFileIndex
.isInContent(subdir
.getVirtualFile())) {
117 if (withSubDirectories
) {
118 children
.add(new PsiDirectoryNode(project
, subdir
, settings
));
121 processPsiDirectoryChildren(psiDirectory
, psiDirectory
.getFiles(), children
, fileIndex
, moduleFileIndex
, settings
,
127 // used only for non-flatten packages mode
128 public void processPsiDirectoryChildren(final PsiDirectory psiDir
,
129 PsiElement
[] children
,
130 List
<AbstractTreeNode
> container
,
131 ProjectFileIndex projectFileIndex
,
132 ModuleFileIndex moduleFileIndex
,
133 ViewSettings viewSettings
,
134 boolean withSubDirectories
) {
135 for (PsiElement child
: children
) {
136 LOG
.assertTrue(child
.isValid());
138 final VirtualFile vFile
;
139 if (child
instanceof PsiFile
) {
140 vFile
= ((PsiFile
)child
).getVirtualFile();
141 addNode(moduleFileIndex
, projectFileIndex
, psiDir
, vFile
, container
, PsiFileNode
.class, child
, viewSettings
);
143 else if (child
instanceof PsiDirectory
) {
144 if (withSubDirectories
) {
145 PsiDirectory dir
= (PsiDirectory
)child
;
146 vFile
= dir
.getVirtualFile();
147 if (!vFile
.equals(projectFileIndex
.getSourceRootForFile(vFile
))) { // if is not a source root
148 if (viewSettings
.isHideEmptyMiddlePackages() && !skipDirectory(psiDir
) && isEmptyMiddleDirectory(dir
, true)) {
149 processPsiDirectoryChildren(dir
, dir
.getChildren(), container
, projectFileIndex
, moduleFileIndex
, viewSettings
,
150 withSubDirectories
); // expand it recursively
154 addNode(moduleFileIndex
, projectFileIndex
, psiDir
, vFile
, container
, PsiDirectoryNode
.class, child
, viewSettings
);
158 LOG
.assertTrue(false, "Either PsiFile or PsiDirectory expected as a child of " + child
.getParent() + ", but was " + child
);
163 public void addNode(ModuleFileIndex moduleFileIndex
,
164 ProjectFileIndex projectFileIndex
,
167 List
<AbstractTreeNode
> container
,
168 Class
<?
extends AbstractTreeNode
> nodeClass
,
170 final ViewSettings settings
) {
174 // this check makes sense for classes not in library content only
175 if (moduleFileIndex
!= null && !moduleFileIndex
.isInContent(vFile
)) {
178 final boolean childInLibraryClasses
= projectFileIndex
.isInLibraryClasses(vFile
);
179 if (!projectFileIndex
.isInSourceContent(vFile
)) {
180 if (childInLibraryClasses
) {
181 final VirtualFile psiDirVFile
= psiDir
.getVirtualFile();
182 final boolean parentInLibraryContent
=
183 projectFileIndex
.isInLibraryClasses(psiDirVFile
) || projectFileIndex
.isInLibrarySource(psiDirVFile
);
184 if (!parentInLibraryContent
) {
189 if (childInLibraryClasses
&& !projectFileIndex
.isInContent(vFile
) && !showFileInLibClasses(vFile
)) {
190 return; // skip java sources in classpath
194 container
.add(ProjectViewNode
.createTreeNode(nodeClass
, element
.getProject(), element
, settings
));
196 catch (Exception e
) {
201 // used only in flatten packages mode
202 public void addAllSubpackages(List
<AbstractTreeNode
> container
,
204 ModuleFileIndex moduleFileIndex
,
205 ViewSettings viewSettings
) {
206 final Project project
= dir
.getProject();
207 PsiDirectory
[] subdirs
= dir
.getSubdirectories();
208 for (PsiDirectory subdir
: subdirs
) {
209 if (skipDirectory(subdir
)) {
212 if (moduleFileIndex
!= null) {
213 if (!moduleFileIndex
.isInContent(subdir
.getVirtualFile())) {
217 if (viewSettings
.isHideEmptyMiddlePackages()) {
218 if (!isEmptyMiddleDirectory(subdir
, false)) {
220 container
.add(new PsiDirectoryNode(project
, subdir
, viewSettings
));
224 container
.add(new PsiDirectoryNode(project
, subdir
, viewSettings
));
226 addAllSubpackages(container
, subdir
, moduleFileIndex
, viewSettings
);