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.ProjectViewPane;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.command.undo.GlobalUndoableAction;
22 import com.intellij.openapi.command.undo.UndoManager;
23 import com.intellij.openapi.editor.Document;
24 import com.intellij.openapi.editor.Editor;
25 import com.intellij.openapi.fileEditor.FileEditorManager;
26 import com.intellij.openapi.module.Module;
27 import com.intellij.openapi.module.ModuleManager;
28 import com.intellij.openapi.module.ModuleUtil;
29 import com.intellij.openapi.project.Project;
30 import com.intellij.openapi.roots.*;
31 import com.intellij.openapi.vfs.VfsUtil;
32 import com.intellij.openapi.vfs.VirtualFile;
33 import com.intellij.openapi.wm.ToolWindow;
34 import com.intellij.openapi.wm.ToolWindowId;
35 import com.intellij.openapi.wm.ToolWindowManager;
36 import com.intellij.psi.*;
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 PsiDirectory[] directories = suggestMostAppropriateDirectories(psiPackage);
141 if (directories.length == 0) return;
142 projectView.getProjectViewPaneById(ProjectViewPane.ID).select(directories[0], directories[0].getVirtualFile(), requestFocus);
147 private static PsiDirectory[] suggestMostAppropriateDirectories(PsiPackage psiPackage) {
148 final Project project = psiPackage.getProject();
149 PsiDirectory[] directories = null;
150 final Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
151 if (editor != null) {
152 final Document document = editor.getDocument();
153 final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
154 if (psiFile != null) {
155 final Module module = ModuleUtil.findModuleForPsiElement(psiFile);
156 if (module != null) {
157 directories = psiPackage.getDirectories(GlobalSearchScope.moduleWithDependenciesScope(module));
159 directories = psiPackage.getDirectories(GlobalSearchScope.notScope(GlobalSearchScope.projectScope(project)));
164 if (directories == null || directories.length == 0) {
165 directories = psiPackage.getDirectories();
171 public boolean packagePrefixExists(PsiPackage psiPackage) {
172 return PackagePrefixElementFinder.getInstance(psiPackage.getProject()).packagePrefixExists(psiPackage.getQualifiedName());
176 public Object[] getDirectoryCachedValueDependencies(PsiPackage psiPackage) {
177 return new Object[] { PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, ProjectRootManager.getInstance(psiPackage.getProject()) };