/* * Copyright 2000-2012 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. */ package com.intellij.openapi.roots.impl; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileTypeRegistry; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ContentIterator; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import consulo.roots.ContentFolderScopes; import consulo.roots.ContentFolderTypeProvider; import consulo.roots.impl.ProductionResourceContentFolderTypeProvider; import consulo.roots.impl.TestResourceContentFolderTypeProvider; import java.util.Arrays; import java.util.List; public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIndex { public static final Logger LOGGER = Logger.getInstance(ProjectFileIndexImpl.class); private final Project myProject; private final ContentFilter myContentFilter; public ProjectFileIndexImpl(@NotNull Project project, @NotNull DirectoryIndex directoryIndex, @NotNull FileTypeRegistry fileTypeManager) { super(directoryIndex, fileTypeManager, project); myProject = project; myContentFilter = new ContentFilter(); } @Override public boolean iterateContent(@NotNull ContentIterator iterator) { Module[] modules = ModuleManager.getInstance(myProject).getModules(); for (Module module : modules) { if (module.isDisposed()) continue; VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); for (VirtualFile contentRoot : contentRoots) { DirectoryInfo info = getInfoForFileOrDirectory(contentRoot); if (!module.equals(info.getModule())) continue; // maybe 2 modules have the same content root? VirtualFile parent = contentRoot.getParent(); if (parent != null) { DirectoryInfo parentInfo = getInfoForFileOrDirectory(parent); if (parentInfo.getModule() != null) continue; // inner content - skip it } boolean finished = VfsUtilCore.iterateChildrenRecursively(contentRoot, myContentFilter, iterator); if (!finished) return false; } } return true; } @Override public boolean iterateContentUnderDirectory(@NotNull VirtualFile dir, @NotNull ContentIterator iterator) { return VfsUtilCore.iterateChildrenRecursively(dir, myContentFilter, iterator); } @Override public boolean isIgnored(@NotNull VirtualFile file) { return isExcluded(file); } @Override public boolean isExcluded(@NotNull VirtualFile file) { DirectoryInfo info = getInfoForFileOrDirectory(file); return info.isIgnored() || info.isExcluded(); } @Override public boolean isUnderIgnored(@NotNull VirtualFile file) { return getInfoForFileOrDirectory(file).isIgnored(); } @Override public Module getModuleForFile(@NotNull VirtualFile file) { return getModuleForFile(file, true); } @Nullable @Override public Module getModuleForFile(@NotNull VirtualFile file, boolean honorExclusion) { if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate(); DirectoryInfo info = getInfoForFileOrDirectory(file); if (info.isInProject() || !honorExclusion && info.isExcluded()) { return info.getModule(); } return null; } @Override @NotNull public List<OrderEntry> getOrderEntriesForFile(@NotNull VirtualFile file) { return Arrays.asList(myDirectoryIndex.getOrderEntries(getInfoForFileOrDirectory(file))); } @Override public VirtualFile getClassRootForFile(@NotNull VirtualFile file) { final DirectoryInfo info = getInfoForFileOrDirectory(file); if (!info.isInProject()) return null; return info.getLibraryClassRoot(); } @Override public VirtualFile getSourceRootForFile(@NotNull VirtualFile file) { final DirectoryInfo info = getInfoForFileOrDirectory(file); if (!info.isInProject()) return null; return info.getSourceRoot(); } @Override public VirtualFile getContentRootForFile(@NotNull VirtualFile file) { return getContentRootForFile(file, true); } @Override public VirtualFile getContentRootForFile(@NotNull VirtualFile file, final boolean honorExclusion) { final DirectoryInfo info = getInfoForFileOrDirectory(file); if (info.isInProject() || !honorExclusion && info.isExcluded()) { return info.getContentRoot(); } return null; } @Nullable @Override public ContentFolderTypeProvider getContentFolderTypeForFile(@NotNull VirtualFile file) { final DirectoryInfo info = getInfoForFileOrDirectory(file); return myDirectoryIndex.getContentFolderType(info); } @Override public String getPackageNameByDirectory(@NotNull VirtualFile dir) { LOGGER.assertTrue(dir.isDirectory()); return myDirectoryIndex.getPackageName(dir); } @Override public boolean isLibraryClassFile(@NotNull VirtualFile file) { if (file.isDirectory()) return false; DirectoryInfo parentInfo = getInfoForFileOrDirectory(file); return parentInfo.isInProject() && parentInfo.hasLibraryClassRoot(); } @Override public boolean isInSource(@NotNull VirtualFile fileOrDir) { DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir); return (info.isInModuleSource() || info.isInLibrarySource()); } @Override public boolean isInResource(@NotNull VirtualFile fileOrDir) { DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir); return info.isInModuleSource() && myDirectoryIndex.getContentFolderType(info) == ProductionResourceContentFolderTypeProvider.getInstance(); } @Override public boolean isInTestResource(@NotNull VirtualFile fileOrDir) { DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir); return info.isInModuleSource() && myDirectoryIndex.getContentFolderType(info) == TestResourceContentFolderTypeProvider.getInstance(); } @Override public boolean isInLibraryClasses(@NotNull VirtualFile fileOrDir) { DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir); return info.hasLibraryClassRoot(); } @Override public boolean isInLibrarySource(@NotNull VirtualFile fileOrDir) { DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir); return info.isInLibrarySource(); } @Override public boolean isInContent(@NotNull VirtualFile fileOrDir) { DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir); return info.isInProject() && info.getModule() != null; } @Override public boolean isInSourceContent(@NotNull VirtualFile fileOrDir) { return getInfoForFileOrDirectory(fileOrDir).isInModuleSource(); } @Override public boolean isInTestSourceContent(@NotNull VirtualFile fileOrDir) { DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir); return info.isInModuleSource() && ContentFolderScopes.test().apply(myDirectoryIndex.getContentFolderType(info)); } private class ContentFilter implements VirtualFileFilter { @Override public boolean accept(@NotNull VirtualFile file) { DirectoryInfo info = getInfoForFileOrDirectory(file); if (info.getModule() == null) return false; if (file.isDirectory()) { return true; } else { return !myFileTypeRegistry.isFileIgnored(file); } } } }