@Override public <S> List<S> filterUniqueRoots( final List<S> in, final Convertor<S, VirtualFile> convertor) { Collections.sort( in, new ComparatorDelegate<S, VirtualFile>(convertor, FilePathComparator.getInstance())); for (int i = 1; i < in.size(); i++) { final S sChild = in.get(i); final VirtualFile child = convertor.convert(sChild); final VirtualFile childRoot = GitUtil.gitRootOrNull(child); if (childRoot == null) { // non-git file actually, skip it continue; } for (int j = i - 1; j >= 0; --j) { final S sParent = in.get(j); final VirtualFile parent = convertor.convert(sParent); // the method check both that parent is an ancestor of the child and that they share common // git root if (VfsUtilCore.isAncestor(parent, child, false) && VfsUtilCore.isAncestor(childRoot, parent, false)) { in.remove(i); //noinspection AssignmentToForLoopParameter --i; break; } } } return in; }
private int compareByLibDir( @NotNull VirtualFile m1File, @NotNull VirtualFile m2File, @Nullable VirtualFile libDir) { if (libDir == null) return COMPARE_NO_RESULT; boolean m1InLib = VfsUtilCore.isAncestor(libDir, m1File, true); boolean m2InLib = VfsUtilCore.isAncestor(libDir, m2File, true); if (m1InLib || m2InLib) { return (m1InLib ? -1 : 0) + (m2InLib ? 1 : 0); } return COMPARE_NO_RESULT; }
@NotNull private static Collection<VirtualFile> gatherIncludeRoots( Collection<VirtualFile> goPathSourcesRoots, Set<VirtualFile> excludeRoots) { Collection<VirtualFile> includeRoots = ContainerUtil.newHashSet(); for (VirtualFile goPathSourcesDirectory : goPathSourcesRoots) { ProgressIndicatorProvider.checkCanceled(); boolean excludedRootIsAncestor = false; for (VirtualFile excludeRoot : excludeRoots) { ProgressIndicatorProvider.checkCanceled(); if (VfsUtilCore.isAncestor(excludeRoot, goPathSourcesDirectory, false)) { excludedRootIsAncestor = true; break; } } if (excludedRootIsAncestor) { continue; } for (VirtualFile file : goPathSourcesDirectory.getChildren()) { ProgressIndicatorProvider.checkCanceled(); if (file.isDirectory() && !excludeRoots.contains(file)) { includeRoots.add(file); } } } return includeRoots; }
final boolean allowVisitChildren(@NotNull VirtualFile file) { if (!file.is(VFileProperty.SYMLINK)) { return true; } if (!myFollowSymLinks || VfsUtilCore.isInvalidLink(file)) { return false; } VirtualFile target = file.getCanonicalFile(); List<VirtualFile> links = myVisitedTargets.get(target); if (links == null) { myVisitedTargets.put(target, ContainerUtil.newSmartList(file)); return true; } boolean hasLoop = false; for (VirtualFile link : links) { if (VfsUtilCore.isAncestor(link, file, true)) { hasLoop = true; break; } } links.add(file); return !hasLoop; }
@Nullable private static ContentEntry findContentEntry(ModuleRootModel rootModel, VirtualFile file) { return ContainerUtil.find( rootModel.getContentEntries(), object -> { VirtualFile entryRoot = object.getFile(); return entryRoot != null && VfsUtilCore.isAncestor(entryRoot, file, false); }); }
// inner roots disclosed public static List<VirtualFile> getRootsUnder( final List<VirtualFile> roots, final VirtualFile underWhat) { final List<VirtualFile> result = new ArrayList<VirtualFile>(roots.size()); for (VirtualFile root : roots) { if (VfsUtilCore.isAncestor(underWhat, root, false)) { result.add(root); } } return result; }
private void annotateExternally( @NotNull final VirtualFile file, @NotNull final PsiModifierListOwner listOwner, @NotNull Project project, @NotNull final String packageName, final VirtualFile virtualFile, @NotNull final String annotationFQName, @NotNull final PsiFile fromFile, final PsiNameValuePair[] value) { final XmlFile[] annotationsXml = new XmlFile[1]; List<XmlFile> xmlFiles = findExternalAnnotationsXmlFiles(listOwner); if (xmlFiles != null) { for (XmlFile xmlFile : xmlFiles) { final VirtualFile vXmlFile = xmlFile.getVirtualFile(); assert vXmlFile != null; if (VfsUtilCore.isAncestor(file, vXmlFile, false)) { annotationsXml[0] = xmlFile; if (!CodeInsightUtilBase.preparePsiElementForWrite(xmlFile)) return; } } } else { xmlFiles = new ArrayList<XmlFile>(); } final List<PsiFile> annotationFiles = new ArrayList<PsiFile>(xmlFiles); new WriteCommandAction(project) { @Override protected void run(final Result result) throws Throwable { if (annotationsXml[0] == null) { annotationsXml[0] = createAnnotationsXml(file, packageName); } if (annotationsXml[0] != null) { annotationFiles.add(annotationsXml[0]); myExternalAnnotations.put(getFQN(packageName, virtualFile), annotationFiles); annotateExternally(listOwner, annotationFQName, annotationsXml[0], fromFile, value); } } }.execute(); UndoManager.getInstance(project) .undoableActionPerformed( new BasicUndoableAction() { @Override public void undo() throws UnexpectedUndoException { dropCache(); } @Override public void redo() throws UnexpectedUndoException { dropCache(); } }); }
@Nullable public static ContentEntry findContentEntryForRoot( @NotNull ModifiableRootModel model, @NotNull VirtualFile root) { ContentEntry contentEntry = null; for (ContentEntry candidate : model.getContentEntries()) { VirtualFile contentRoot = candidate.getFile(); if (contentRoot != null && VfsUtilCore.isAncestor(contentRoot, root, false)) { contentEntry = candidate; } } return contentEntry; }
@Nullable private static VirtualFile guessRootForVcs( @NotNull Project project, @Nullable AbstractVcs vcs, @Nullable String defaultRootPathValue) { if (project.isDisposed()) return null; LOG.debug("Guessing vcs root..."); ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); if (vcs == null) { LOG.debug("Vcs not found."); return null; } String vcsName = vcs.getDisplayName(); VirtualFile[] vcsRoots = vcsManager.getRootsUnderVcs(vcs); if (vcsRoots.length == 0) { LOG.debug("No " + vcsName + " roots in the project."); return null; } if (vcsRoots.length == 1) { VirtualFile onlyRoot = vcsRoots[0]; LOG.debug("Only one " + vcsName + " root in the project, returning: " + onlyRoot); return onlyRoot; } // get remembered last visited repository root if (defaultRootPathValue != null) { VirtualFile recentRoot = VcsUtil.getVirtualFile(defaultRootPathValue); if (recentRoot != null) { LOG.debug("Returning the recent root: " + recentRoot); return recentRoot; } } // otherwise return the root of the project dir or the root containing the project dir, if there // is such VirtualFile projectBaseDir = project.getBaseDir(); if (projectBaseDir == null) { VirtualFile firstRoot = vcsRoots[0]; LOG.debug("Project base dir is null, returning the first root: " + firstRoot); return firstRoot; } VirtualFile rootCandidate; for (VirtualFile root : vcsRoots) { if (root.equals(projectBaseDir) || VfsUtilCore.isAncestor(root, projectBaseDir, true)) { LOG.debug("The best candidate: " + root); return root; } } rootCandidate = vcsRoots[0]; LOG.debug("Returning the best candidate: " + rootCandidate); return rootCandidate; }
private boolean isInDirectoryBasedRoot(final VirtualFile file) { if (file == null) return false; final StorageScheme storageScheme = ((ProjectEx) myProject).getStateStore().getStorageScheme(); if (StorageScheme.DIRECTORY_BASED.equals(storageScheme)) { final VirtualFile baseDir = myProject.getBaseDir(); if (baseDir == null) return false; final VirtualFile ideaDir = baseDir.findChild(Project.DIRECTORY_STORE_FOLDER); return ideaDir != null && ideaDir.isValid() && ideaDir.isDirectory() && VfsUtilCore.isAncestor(ideaDir, file, false); } return false; }
@Override public void fileMoved(@NotNull VirtualFileMoveEvent event) { String dirName = event.getFileName(); String ancestorPath = event.getOldParent().getPath() + "/" + dirName; String moduleFilePath = getModuleFilePath(); if (VfsUtilCore.isAncestor(new File(ancestorPath), new File(moduleFilePath), true)) { setModuleFilePath( event.getNewParent().getPath() + "/" + dirName + "/" + FileUtil.getRelativePath(ancestorPath, moduleFilePath, '/')); } }
@Nullable private static XmlFile findXmlFileInRoot( @Nullable List<XmlFile> xmlFiles, @NotNull VirtualFile root) { if (xmlFiles != null) { for (XmlFile xmlFile : xmlFiles) { VirtualFile vf = xmlFile.getVirtualFile(); if (vf != null) { if (VfsUtilCore.isAncestor(root, vf, false)) { return xmlFile; } } } } return null; }
@Nullable private static VirtualFile getVcsRootForLibraryFile( @NotNull Project project, @NotNull VirtualFile file) { ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); // for a file inside .jar/.zip consider the .jar/.zip file itself VirtualFile root = vcsManager.getVcsRootFor(VfsUtilCore.getVirtualFileForJar(file)); if (root != null) { LOGGER.debug("Found root for zip/jar file: " + root); return root; } // for other libs which don't have jars inside the project dir (such as JDK) take the owner // module of the lib List<OrderEntry> entries = ProjectRootManager.getInstance(project).getFileIndex().getOrderEntriesForFile(file); Set<VirtualFile> libraryRoots = new HashSet<VirtualFile>(); for (OrderEntry entry : entries) { if (entry instanceof LibraryOrderEntry || entry instanceof JdkOrderEntry) { VirtualFile moduleRoot = vcsManager.getVcsRootFor(entry.getOwnerModule().getModuleFile()); if (moduleRoot != null) { libraryRoots.add(moduleRoot); } } } if (libraryRoots.size() == 0) { LOGGER.debug("No library roots"); return null; } // if the lib is used in several modules, take the top module // (for modules of the same level we can't guess anything => take the first one) Iterator<VirtualFile> libIterator = libraryRoots.iterator(); VirtualFile topLibraryRoot = libIterator.next(); while (libIterator.hasNext()) { VirtualFile libRoot = libIterator.next(); if (VfsUtilCore.isAncestor(libRoot, topLibraryRoot, true)) { topLibraryRoot = libRoot; } } LOGGER.debug("Several library roots, returning " + topLibraryRoot); return topLibraryRoot; }
@Override public boolean isGenerated(VirtualFile file) { if (myGeneratedSources.contains(FileBasedIndex.getFileId(file))) { return true; } if (isUnderRoots(myRootToModuleMap.keySet(), file)) { return true; } final Module module = getModuleByFile(file); if (module != null) { for (AdditionalOutputDirectoriesProvider provider : AdditionalOutputDirectoriesProvider.EP_NAME.getExtensions()) { for (String path : provider.getOutputDirectories(getProject(), module)) { if (path != null && VfsUtilCore.isAncestor(new File(path), new File(file.getPath()), true)) { return true; } } } } return false; }
@Override public void propertyChanged(@NotNull VirtualFilePropertyEvent event) { if (!isModuleAdded || event.getRequestor() instanceof StateStorage || !VirtualFile.PROP_NAME.equals(event.getPropertyName())) { return; } VirtualFile parent = event.getParent(); if (parent != null) { String parentPath = parent.getPath(); String ancestorPath = parentPath + "/" + event.getOldValue(); String moduleFilePath = getModuleFilePath(); if (VfsUtilCore.isAncestor(new File(ancestorPath), new File(moduleFilePath), true)) { setModuleFilePath( parentPath + "/" + event.getNewValue() + "/" + FileUtil.getRelativePath(ancestorPath, moduleFilePath, '/')); } } }
public void apply() throws ConfigurationException { // validate content and source roots final Map<VirtualFile, String> contentRootToModuleNameMap = new HashMap<VirtualFile, String>(); final Map<VirtualFile, VirtualFile> srcRootsToContentRootMap = new HashMap<VirtualFile, VirtualFile>(); for (final ModuleEditor moduleEditor : myModuleEditors.values()) { final ModifiableRootModel rootModel = moduleEditor.getModifiableRootModel(); final ContentEntry[] contents = rootModel.getContentEntries(); for (ContentEntry contentEntry : contents) { final VirtualFile contentRoot = contentEntry.getFile(); if (contentRoot == null) { continue; } final String moduleName = moduleEditor.getName(); final String previousName = contentRootToModuleNameMap.put(contentRoot, moduleName); if (previousName != null && !previousName.equals(moduleName)) { throw new ConfigurationException( ProjectBundle.message( "module.paths.validation.duplicate.content.error", contentRoot.getPresentableUrl(), previousName, moduleName)); } for (VirtualFile srcRoot : contentEntry.getSourceFolderFiles()) { final VirtualFile anotherContentRoot = srcRootsToContentRootMap.put(srcRoot, contentRoot); if (anotherContentRoot != null) { final String problematicModule; final String correctModule; if (VfsUtilCore.isAncestor(anotherContentRoot, contentRoot, true)) { problematicModule = contentRootToModuleNameMap.get(anotherContentRoot); correctModule = contentRootToModuleNameMap.get(contentRoot); } else { problematicModule = contentRootToModuleNameMap.get(contentRoot); correctModule = contentRootToModuleNameMap.get(anotherContentRoot); } throw new ConfigurationException( ProjectBundle.message( "module.paths.validation.duplicate.source.root.error", problematicModule, srcRoot.getPresentableUrl(), correctModule)); } } } } // additional validation: directories marked as src roots must belong to the same module as // their corresponding content root for (Map.Entry<VirtualFile, VirtualFile> entry : srcRootsToContentRootMap.entrySet()) { final VirtualFile srcRoot = entry.getKey(); final VirtualFile correspondingContent = entry.getValue(); final String expectedModuleName = contentRootToModuleNameMap.get(correspondingContent); for (VirtualFile candidateContent = srcRoot; candidateContent != null && !candidateContent.equals(correspondingContent); candidateContent = candidateContent.getParent()) { final String moduleName = contentRootToModuleNameMap.get(candidateContent); if (moduleName != null && !moduleName.equals(expectedModuleName)) { throw new ConfigurationException( ProjectBundle.message( "module.paths.validation.source.root.belongs.to.another.module.error", srcRoot.getPresentableUrl(), expectedModuleName, moduleName)); } } } final List<ModifiableRootModel> models = new ArrayList<ModifiableRootModel>(myModuleEditors.size()); for (ModuleEditor moduleEditor : myModuleEditors.values()) { moduleEditor.canApply(); } final Map<Sdk, Sdk> modifiedToOriginalMap = new HashMap<Sdk, Sdk>(); final ProjectSdksModel projectJdksModel = ProjectStructureConfigurable.getInstance(myProject).getProjectJdksModel(); for (Map.Entry<Sdk, Sdk> entry : projectJdksModel.getProjectSdks().entrySet()) { modifiedToOriginalMap.put(entry.getValue(), entry.getKey()); } final Ref<ConfigurationException> exceptionRef = Ref.create(); DumbService.getInstance(myProject) .allowStartingDumbModeInside( DumbModePermission.MAY_START_BACKGROUND, new Runnable() { public void run() { ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { try { for (final ModuleEditor moduleEditor : myModuleEditors.values()) { final ModifiableRootModel model = moduleEditor.apply(); if (model != null) { if (!model.isSdkInherited()) { // make sure the sdk is set to original SDK stored in the JDK // Table final Sdk modelSdk = model.getSdk(); if (modelSdk != null) { final Sdk original = modifiedToOriginalMap.get(modelSdk); if (original != null) { model.setSdk(original); } } } models.add(model); } } myFacetsConfigurator.applyEditors(); } catch (ConfigurationException e) { exceptionRef.set(e); return; } try { final ModifiableRootModel[] rootModels = models.toArray(new ModifiableRootModel[models.size()]); ModifiableModelCommitter.multiCommit(rootModels, myModuleModel); myModuleModelCommitted = true; myFacetsConfigurator.commitFacets(); } finally { ModuleStructureConfigurable.getInstance(myProject) .getFacetEditorFacade() .clearMaps(false); myFacetsConfigurator = createFacetsConfigurator(); myModuleModel = ModuleManager.getInstance(myProject).getModifiableModel(); myModuleModelCommitted = false; } } }); } }); if (!exceptionRef.isNull()) { throw exceptionRef.get(); } myModified = false; }