From a347a09f02d629ba656d6a778c8734cde900c660 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Sat, 25 Aug 2012 23:51:01 +0400 Subject: [PATCH] Use VFS visitor in place of recursion (maven) --- .../maven/compiler/MavenResourceCompiler.java | 103 ++++++++---------- .../project/MavenProjectsManagerWatcher.java | 33 +++--- .../idea/maven/utils/FileFinder.java | 55 ++++++---- 3 files changed, 96 insertions(+), 95 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java index 5aeb6f81c74f..5bfcb796f12d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java @@ -31,10 +31,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.*; import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.containers.CollectionFactory; import gnu.trove.THashMap; @@ -295,65 +292,55 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler { return result; } - private static void collectProcessingItems(Module module, - VirtualFile sourceRoot, + private static void collectProcessingItems(final Module module, + final VirtualFile sourceRoot, VirtualFile currentDir, - String outputDir, - List includes, - List excludes, - boolean isSourceRootFiltered, - Properties properties, - long propertiesHashCode, - Set nonFilteredExtensions, - String escapeString, - List result, - ProgressIndicator indicator) { - indicator.checkCanceled(); + final String outputDir, + final List includes, + final List excludes, + final boolean isSourceRootFiltered, + final Properties properties, + final long propertiesHashCode, + final Set nonFilteredExtensions, + final String escapeString, + final List result, + final ProgressIndicator indicator) { + VfsUtilCore.visitChildrenRecursively(currentDir, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + indicator.checkCanceled(); - for (VirtualFile eachSourceFile : currentDir.getChildren()) { - if (eachSourceFile.isDirectory()) { - collectProcessingItems(module, - sourceRoot, - eachSourceFile, - outputDir, - includes, - excludes, - isSourceRootFiltered, - properties, - propertiesHashCode, - nonFilteredExtensions, - escapeString, - result, - indicator); - } - else { - String relPath = VfsUtilCore.getRelativePath(eachSourceFile, sourceRoot, '/'); - if (relPath == null) { - MavenLog.LOG.error("Cannot calculate relate path for file: " + eachSourceFile + " in root: " + sourceRoot); - continue; + if (!file.isDirectory()) { + String relPath = VfsUtilCore.getRelativePath(file, sourceRoot, '/'); + if (relPath == null) { + MavenLog.LOG.error("Cannot calculate relate path for file: " + file + " in root: " + sourceRoot); + return true; + } + + ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex(); + if (fileIndex.isIgnored(file)) return true; + if (!MavenUtil.isIncluded(relPath, includes, excludes)) return true; + + String outputPath = outputDir + "/" + relPath; + long outputFileTimestamp = -1; + File outputFile = new File(outputPath); + if (outputFile.exists()) { + outputFileTimestamp = outputFile.lastModified(); + } + boolean isFiltered = isSourceRootFiltered && !nonFilteredExtensions.contains(file.getExtension()); + result.add(new MyProcessingItem(module, + file, + outputPath, + outputFileTimestamp, + isFiltered, + properties, + propertiesHashCode, + escapeString)); } - ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex(); - if (fileIndex.isIgnored(eachSourceFile)) continue; - if (!MavenUtil.isIncluded(relPath, includes, excludes)) continue; - - String outputPath = outputDir + "/" + relPath; - long outputFileTimestamp = -1; - File outputFile = new File(outputPath); - if (outputFile.exists()) { - outputFileTimestamp = outputFile.lastModified(); - } - boolean isFiltered = isSourceRootFiltered && !nonFilteredExtensions.contains(eachSourceFile.getExtension()); - result.add(new MyProcessingItem(module, - eachSourceFile, - outputPath, - outputFileTimestamp, - isFiltered, - properties, - propertiesHashCode, - escapeString)); + return true; } - } + }); } private void collectItemsToDelete(Module module, List processingItems, List result) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java index 1c35a719ad44..5acfe28fadad 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -33,10 +33,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.events.*; @@ -209,7 +206,7 @@ public class MavenProjectsManagerWatcher { String path = getNormalizedPath(settingsFile); if (path != null) { - String url = VfsUtil.pathToUrl(path); + String url = VfsUtilCore.pathToUrl(path); mySettingsFilesPointers.add( VirtualFilePointerManager.getInstance().create(url, myChangedDocumentsQueue, new VirtualFilePointerListener() { @Override @@ -402,6 +399,7 @@ public class MavenProjectsManagerWatcher { } } + @Nullable private VirtualFile getPomFileProfilesFile(VirtualFile f) { if (!f.getName().equals(MavenConstants.PROFILES_XML)) return null; return f.getParent().findChild(MavenConstants.POM_XML); @@ -432,7 +430,7 @@ public class MavenProjectsManagerWatcher { // Do not use before() method to initialize the lists // since the listener can be attached during the update // and before method can be skipped. - // The better way to fix if, of course, is to do simething with + // The better way to fix if, of course, is to do something with // subscription - add listener not during postStartupActivity // but on project initialization to avoid this situation. if (areFileSetsInitialised()) return; @@ -483,16 +481,19 @@ public class MavenProjectsManagerWatcher { } private void deleteRecursively(VirtualFile f) { - if (isRelevant(f.getPath())) deleteFile(f); - if (f.isDirectory()) { - // prevent reading directories content if not already cached. - Iterable children = f instanceof NewVirtualFile - ? ((NewVirtualFile)f).iterInDbChildren() - : Arrays.asList(f.getChildren()); - for (VirtualFile each : children) { - deleteRecursively(each); + VfsUtilCore.visitChildrenRecursively(f, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile f) { + if (isRelevant(f.getPath())) deleteFile(f); + return true; } - } + + @Nullable + @Override + public Iterable getChildrenIterable(@NotNull VirtualFile f) { + return f.isDirectory() && f instanceof NewVirtualFile ? ((NewVirtualFile)f).iterInDbChildren() : null; + } + }); } @Override diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/FileFinder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/FileFinder.java index 6e9d0a933841..d11351df21ee 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/FileFinder.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/FileFinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -16,38 +16,51 @@ package org.jetbrains.idea.maven.utils; import com.intellij.openapi.vfs.InvalidVirtualFileAccessException; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; +import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.model.MavenConstants; import java.util.List; public class FileFinder { public static List findPomFiles(VirtualFile[] roots, - boolean lookForNested, - MavenProgressIndicator indicator, - List result) throws MavenProcessCanceledException { + final boolean lookForNested, + final MavenProgressIndicator indicator, + final List result) throws MavenProcessCanceledException { for (VirtualFile f : roots) { - indicator.checkCanceled(); + VfsUtilCore.visitChildrenRecursively(f, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile f) { + try { + indicator.checkCanceled(); + indicator.setText2(f.getPath()); - try { - indicator.setText2(f.getPath()); - - if (f.isDirectory()) { - if (lookForNested) { - f.refresh(false, false); - findPomFiles(f.getChildren(), lookForNested, indicator, result); + if (f.isDirectory()) { + if (lookForNested) { + f.refresh(false, false); + } + else { + return false; + } + } + else { + if (f.getName().equalsIgnoreCase(MavenConstants.POM_XML)) { + result.add(f); + } + } } - } - else { - if (f.getName().equalsIgnoreCase(MavenConstants.POM_XML)) { - result.add(f); + catch (InvalidVirtualFileAccessException e) { + // we are accessing VFS without read action here so such exception may occasionally occur + MavenLog.LOG.info(e); } + catch (MavenProcessCanceledException e) { + throw new VisitorException(e); + } + return true; } - } - catch (InvalidVirtualFileAccessException e) { - // we are accessing VFS without read action here so such exception may occasionally occur - MavenLog.LOG.info(e); - } + }, MavenProcessCanceledException.class); } return result;