2 * Copyright 2000-2011 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.psi.impl.file;
18 import com.intellij.ide.projectView.ProjectView;
19 import com.intellij.ide.projectView.impl.PackageViewPane;
20 import com.intellij.ide.projectView.impl.ProjectRootsUtil;
21 import com.intellij.ide.projectView.impl.nodes.PackageElement;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.command.undo.GlobalUndoableAction;
24 import com.intellij.openapi.command.undo.UndoManager;
25 import com.intellij.openapi.module.Module;
26 import com.intellij.openapi.module.ModuleManager;
27 import com.intellij.openapi.project.Project;
28 import com.intellij.openapi.roots.*;
29 import com.intellij.openapi.vfs.VfsUtil;
30 import com.intellij.openapi.vfs.VirtualFile;
31 import com.intellij.openapi.wm.ToolWindow;
32 import com.intellij.openapi.wm.ToolWindowId;
33 import com.intellij.openapi.wm.ToolWindowManager;
34 import com.intellij.psi.NonClasspathClassFinder;
35 import com.intellij.psi.PsiDirectory;
36 import com.intellij.psi.PsiPackage;
37 import com.intellij.psi.impl.PackagePrefixElementFinder;
38 import com.intellij.psi.search.GlobalSearchScope;
39 import com.intellij.psi.util.PsiModificationTracker;
41 import java.util.ArrayList;
42 import java.util.List;
47 public class PsiPackageImplementationHelperImpl extends PsiPackageImplementationHelper {
49 public GlobalSearchScope adjustAllScope(PsiPackage psiPackage, GlobalSearchScope globalSearchScope) {
50 return NonClasspathClassFinder.addNonClasspathScope(psiPackage.getProject(), globalSearchScope);
54 public VirtualFile[] occursInPackagePrefixes(PsiPackage psiPackage) {
55 List<VirtualFile> result = new ArrayList<VirtualFile>();
56 final Module[] modules = ModuleManager.getInstance(psiPackage.getProject()).getModules();
58 for (final Module module : modules) {
59 final ContentEntry[] contentEntries = ModuleRootManager.getInstance(module).getContentEntries();
60 for (final ContentEntry contentEntry : contentEntries) {
61 final SourceFolder[] sourceFolders = contentEntry.getSourceFolders();
62 for (final SourceFolder sourceFolder : sourceFolders) {
63 final String packagePrefix = sourceFolder.getPackagePrefix();
64 if (packagePrefix.startsWith(psiPackage.getQualifiedName())) {
65 final VirtualFile file = sourceFolder.getFile();
74 return VfsUtil.toVirtualFileArray(result);
78 public void handleQualifiedNameChange(final PsiPackage psiPackage, final String newQualifiedName) {
79 ApplicationManager.getApplication().assertWriteAccessAllowed();
80 final String oldQualifedName = psiPackage.getQualifiedName();
81 final boolean anyChanged = changePackagePrefixes(psiPackage, oldQualifedName, newQualifiedName);
83 UndoManager.getInstance(psiPackage.getProject()).undoableActionPerformed(new GlobalUndoableAction() {
86 changePackagePrefixes(psiPackage, newQualifiedName, oldQualifedName);
91 changePackagePrefixes(psiPackage, oldQualifedName, newQualifiedName);
97 private static boolean changePackagePrefixes(PsiPackage psiPackage, final String oldQualifiedName, final String newQualifiedName) {
98 final Module[] modules = ModuleManager.getInstance(psiPackage.getProject()).getModules();
99 List<ModifiableRootModel> modelsToCommit = new ArrayList<ModifiableRootModel>();
100 for (final Module module : modules) {
101 boolean anyChange = false;
102 final ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
103 final ContentEntry[] contentEntries = rootModel.getContentEntries();
104 for (final ContentEntry contentEntry : contentEntries) {
105 final SourceFolder[] sourceFolders = contentEntry.getSourceFolders();
106 for (final SourceFolder sourceFolder : sourceFolders) {
107 final String packagePrefix = sourceFolder.getPackagePrefix();
108 if (packagePrefix.startsWith(oldQualifiedName)) {
109 sourceFolder.setPackagePrefix(newQualifiedName + packagePrefix.substring(oldQualifiedName.length()));
115 modelsToCommit.add(rootModel);
121 if (!modelsToCommit.isEmpty()) {
122 ProjectRootManager.getInstance(psiPackage.getProject()).multiCommit(
123 modelsToCommit.toArray(new ModifiableRootModel[modelsToCommit.size()])
132 public void navigate(final PsiPackage psiPackage, final boolean requestFocus) {
133 final Project project = psiPackage.getProject();
134 ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.PROJECT_VIEW);
135 window.activate(null);
136 window.getActivation().doWhenDone(new Runnable() {
139 final ProjectView projectView = ProjectView.getInstance(project);
140 projectView.changeView(PackageViewPane.ID);
141 final PsiDirectory[] directories = psiPackage.getDirectories();
142 final VirtualFile firstDir = directories[0].getVirtualFile();
143 final boolean isLibraryRoot = ProjectRootsUtil.isLibraryRoot(firstDir, project);
145 final Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(firstDir);
146 final PackageElement packageElement = new PackageElement(module, psiPackage, isLibraryRoot);
147 projectView.getProjectViewPaneById(PackageViewPane.ID).select(packageElement, firstDir, requestFocus);
153 public boolean packagePrefixExists(PsiPackage psiPackage) {
154 return PackagePrefixElementFinder.getInstance(psiPackage.getProject()).packagePrefixExists(psiPackage.getQualifiedName());
158 public Object[] getDirectoryCachedValueDependencies(PsiPackage psiPackage) {
159 return new Object[] { PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, ProjectRootManager.getInstance(psiPackage.getProject()) };