2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.ide
.projectView
.impl
.nodes
;
18 import com
.intellij
.ide
.projectView
.ViewSettings
;
19 import com
.intellij
.ide
.util
.treeView
.AbstractTreeNode
;
20 import com
.intellij
.ide
.util
.treeView
.TreeViewUtil
;
21 import com
.intellij
.openapi
.module
.Module
;
22 import com
.intellij
.openapi
.module
.ModuleManager
;
23 import com
.intellij
.openapi
.project
.Project
;
24 import com
.intellij
.openapi
.roots
.*;
25 import com
.intellij
.openapi
.util
.Comparing
;
26 import com
.intellij
.openapi
.vfs
.VirtualFile
;
27 import com
.intellij
.psi
.JavaDirectoryService
;
28 import com
.intellij
.psi
.PsiDirectory
;
29 import com
.intellij
.psi
.PsiManager
;
30 import com
.intellij
.psi
.PsiPackage
;
31 import com
.intellij
.psi
.search
.GlobalSearchScope
;
32 import org
.jetbrains
.annotations
.NotNull
;
36 public class PackageUtil
{
38 public static PsiPackage
[] getSubpackages(PsiPackage aPackage
,
40 final Project project
,
41 final boolean searchInLibraries
) {
42 final GlobalSearchScope scopeToShow
= getScopeToShow(project
, module
, searchInLibraries
);
43 final PsiDirectory
[] dirs
= aPackage
.getDirectories(scopeToShow
);
44 final Set
<PsiPackage
> subpackages
= new HashSet
<PsiPackage
>();
45 for (PsiDirectory dir
: dirs
) {
46 final PsiDirectory
[] subdirectories
= dir
.getSubdirectories();
47 for (PsiDirectory subdirectory
: subdirectories
) {
48 final PsiPackage psiPackage
= JavaDirectoryService
.getInstance().getPackage(subdirectory
);
49 if (psiPackage
!= null) {
50 final String name
= psiPackage
.getName();
51 // skip "default" subpackages as they should be attributed to other modules
52 // this is the case when contents of one module is nested into contents of another
53 if (name
!= null && !"".equals(name
)) {
54 subpackages
.add(psiPackage
);
59 return subpackages
.toArray(new PsiPackage
[subpackages
.size()]);
62 public static void addPackageAsChild(final Collection
<AbstractTreeNode
> children
,
63 final PsiPackage aPackage
,
65 ViewSettings settings
,
66 final boolean inLibrary
) {
67 final boolean shouldSkipPackage
= settings
.isHideEmptyMiddlePackages() && isPackageEmpty(aPackage
, module
, !settings
.isFlattenPackages(), inLibrary
);
68 final Project project
= aPackage
.getProject();
69 if (!shouldSkipPackage
) {
70 children
.add(new PackageElementNode(project
,
71 new PackageElement(module
, aPackage
, inLibrary
), settings
));
73 if (settings
.isFlattenPackages() || shouldSkipPackage
) {
74 final PsiPackage
[] subpackages
= getSubpackages(aPackage
, module
, project
, inLibrary
);
75 for (PsiPackage subpackage
: subpackages
) {
76 addPackageAsChild(children
, subpackage
, module
, settings
, inLibrary
);
81 public static boolean isPackageEmpty(PsiPackage aPackage
,
83 boolean strictlyEmpty
,
84 final boolean inLibrary
) {
85 final Project project
= aPackage
.getProject();
86 final GlobalSearchScope scopeToShow
= getScopeToShow(project
, module
, inLibrary
);
87 final PsiDirectory
[] dirs
= aPackage
.getDirectories(scopeToShow
);
88 for (final PsiDirectory dir
: dirs
) {
89 if (!TreeViewUtil
.isEmptyMiddlePackage(dir
, strictlyEmpty
)) {
96 public static GlobalSearchScope
getScopeToShow(final Project project
, final Module module
, boolean forLibraries
) {
99 return new ModuleLibrariesSearchScope(module
);
102 return GlobalSearchScope
.moduleScope(module
);
107 return new ProjectLibrariesSearchScope(project
);
110 return GlobalSearchScope
.projectScope(project
);
116 public static boolean isPackageDefault(PsiPackage directoryPackage
) {
117 final String qName
= directoryPackage
.getQualifiedName();
118 return qName
.length() == 0;
121 public static Collection
<AbstractTreeNode
> createPackageViewChildrenOnFiles(final List
<VirtualFile
> sourceRoots
,
122 final Project project
,
123 final ViewSettings settings
,
125 final boolean inLibrary
) {
126 final PsiManager psiManager
= PsiManager
.getInstance(project
);
128 final List
<AbstractTreeNode
> children
= new ArrayList
<AbstractTreeNode
>();
129 final Set
<PsiPackage
> topLevelPackages
= new HashSet
<PsiPackage
>();
131 for (final VirtualFile root
: sourceRoots
) {
132 final PsiDirectory directory
= psiManager
.findDirectory(root
);
133 if (directory
== null) {
136 final PsiPackage directoryPackage
= JavaDirectoryService
.getInstance().getPackage(directory
);
137 if (directoryPackage
== null || isPackageDefault(directoryPackage
)) {
139 final PsiDirectory
[] subdirectories
= directory
.getSubdirectories();
140 for (PsiDirectory subdirectory
: subdirectories
) {
141 final PsiPackage aPackage
= JavaDirectoryService
.getInstance().getPackage(subdirectory
);
142 if (aPackage
!= null && !isPackageDefault(aPackage
)) {
143 topLevelPackages
.add(aPackage
);
147 children
.addAll(ProjectViewDirectoryHelper
.getInstance(project
).getDirectoryChildren(directory
, settings
, false));
150 topLevelPackages
.add(directoryPackage
);
154 for (final PsiPackage topLevelPackage
: topLevelPackages
) {
155 addPackageAsChild(children
, topLevelPackage
, module
, settings
, inLibrary
);
161 public static String
getNodeName(final ViewSettings settings
, final PsiPackage aPackage
, final PsiPackage parentPackageInTree
, String defaultShortName
,
162 boolean isFQNameShown
) {
165 name
= settings
.isAbbreviatePackageNames() ? TreeViewUtil
.calcAbbreviatedPackageFQName(aPackage
) : aPackage
.getQualifiedName();
167 else if (parentPackageInTree
!= null) {
168 PsiPackage parentPackage
= aPackage
.getParentPackage();
169 final StringBuilder buf
= new StringBuilder();
170 buf
.append(aPackage
.getName());
171 while (parentPackage
!= null && !parentPackage
.equals(parentPackageInTree
)) {
172 final String parentPackageName
= parentPackage
.getName();
173 if (parentPackageName
== null || "".equals(parentPackageName
)) {
174 break; // reached default package
177 buf
.insert(0, parentPackageName
);
178 parentPackage
= parentPackage
.getParentPackage();
180 name
= buf
.toString();
183 name
= defaultShortName
;
188 private static class ModuleLibrariesSearchScope
extends GlobalSearchScope
{
189 private final Module myModule
;
191 public ModuleLibrariesSearchScope(final Module module
) {
192 super(module
.getProject());
196 public boolean contains(VirtualFile file
) {
197 final OrderEntry orderEntry
= ModuleRootManager
.getInstance(myModule
).getFileIndex().getOrderEntryForFile(file
);
198 return orderEntry
instanceof JdkOrderEntry
|| orderEntry
instanceof LibraryOrderEntry
;
201 public int compare(VirtualFile file1
, VirtualFile file2
) {
202 final ModuleFileIndex fileIndex
= ModuleRootManager
.getInstance(myModule
).getFileIndex();
203 return Comparing
.compare(fileIndex
.getOrderEntryForFile(file2
), fileIndex
.getOrderEntryForFile(file1
));
206 public boolean isSearchInModuleContent(@NotNull Module aModule
) {
210 public boolean isSearchInLibraries() {
215 private static class ProjectLibrariesSearchScope
extends GlobalSearchScope
{
217 public ProjectLibrariesSearchScope(final Project project
) {
221 private static Module
[] getModules(final Project project
) {
222 return ModuleManager
.getInstance(project
).getModules();
225 public boolean contains(VirtualFile file
) {
226 final Module
[] modules
= getModules(getProject());
227 for (Module module
: modules
) {
228 final OrderEntry orderEntryForFile
= ModuleRootManager
.getInstance(module
).getFileIndex().getOrderEntryForFile(file
);
229 if (orderEntryForFile
instanceof JdkOrderEntry
|| orderEntryForFile
instanceof LibraryOrderEntry
) return true;
234 public int compare(VirtualFile file1
, VirtualFile file2
) {
235 final Module
[] modules
= getModules(getProject());
236 for (Module module
: modules
) {
237 final ModuleFileIndex fileIndex
= ModuleRootManager
.getInstance(module
).getFileIndex();
238 final OrderEntry orderEntry1
= fileIndex
.getOrderEntryForFile(file1
);
239 if (orderEntry1
!= null) {
240 final OrderEntry orderEntry2
= fileIndex
.getOrderEntryForFile(file2
);
241 if (orderEntry2
!= null) {
242 return orderEntry2
.compareTo(orderEntry1
);
252 public boolean isSearchInModuleContent(@NotNull Module aModule
) {
256 public boolean isSearchInLibraries() {