Acquire read action for VFS visitor

This commit is contained in:
Roman Shevchenko
2012-08-24 22:19:11 +04:00
parent 7c310d870e
commit 30faf5f1ec
3 changed files with 74 additions and 15 deletions
@@ -15,6 +15,8 @@
*/
package com.intellij.openapi.vfs;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream;
import com.intellij.openapi.util.io.FileUtil;
@@ -26,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -184,9 +187,8 @@ public class VfsUtilCore {
return result.skipToParent != root;
}
@SuppressWarnings("UnsafeVfsRecursion")
public static VirtualFileVisitor.Result visitChildrenRecursively(@NotNull VirtualFile file, @NotNull VirtualFileVisitor visitor) {
if (!file.isValid()) return VirtualFileVisitor.CONTINUE;
visitor.pushFrame();
try {
final boolean visited = visitor.allowVisitFile(file);
@@ -195,22 +197,26 @@ public class VfsUtilCore {
if (result.skipChildren) return result;
}
if (!visitor.allowVisitChildren(file)) return VirtualFileVisitor.CONTINUE;
Iterable<VirtualFile> childrenIterable = null;
if (!visitor.depthLimitReached()) {
final Iterable<VirtualFile> iterable = visitor.getChildrenIterable(file);
if (iterable != null) {
for (VirtualFile child : iterable) {
VirtualFileVisitor.Result result = visitChildrenRecursively(child, visitor);
if (result.skipToParent != null && result.skipToParent != child) return result;
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
try {
if (!file.isValid() || !visitor.allowVisitChildren(file)) return VirtualFileVisitor.CONTINUE;
if (!visitor.depthLimitReached()) {
childrenIterable = visitor.getChildrenIterable(file);
if (childrenIterable == null) {
childrenIterable = Arrays.asList(file.getChildren());
}
}
else {
@SuppressWarnings("UnsafeVfsRecursion") VirtualFile[] children = file.getChildren();
for (VirtualFile child : children) {
VirtualFileVisitor.Result result = visitChildrenRecursively(child, visitor);
if (result.skipToParent != null && result.skipToParent != child) return result;
}
}
finally {
token.finish();
}
if (childrenIterable != null) {
for (VirtualFile child : childrenIterable) {
VirtualFileVisitor.Result result = visitChildrenRecursively(child, visitor);
if (result.skipToParent != null && result.skipToParent != child) return result;
}
}
@@ -19,6 +19,7 @@ import com.intellij.mock.MockVirtualFile;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.PlatformUltraLiteTestFixture;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import org.jetbrains.annotations.NotNull;
@@ -32,10 +33,13 @@ import java.util.Collections;
import static org.junit.Assert.assertEquals;
public class VirtualFileVisitorTest {
private static PlatformUltraLiteTestFixture myFixture;
private static VirtualFile myRoot;
@BeforeClass
public static void setUp() throws Exception {
myFixture = PlatformUltraLiteTestFixture.getFixture();
myFixture.setUp();
myRoot =
dir("/",
dir("d1",
@@ -54,6 +58,7 @@ public class VirtualFileVisitorTest {
@AfterClass
public static void tearDown() throws Exception {
myRoot = null;
myFixture.tearDown();
}
@Test
@@ -0,0 +1,48 @@
/*
* 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.testFramework;
import com.intellij.mock.MockApplication;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
public class PlatformUltraLiteTestFixture {
@NotNull
public static PlatformUltraLiteTestFixture getFixture() {
return new PlatformUltraLiteTestFixture();
}
private Disposable myAppDisposable = null;
private PlatformUltraLiteTestFixture() { }
public void setUp() {
final Application application = ApplicationManager.getApplication();
if (application == null) {
myAppDisposable = Disposer.newDisposable();
ApplicationManager.setApplication(new MockApplication(myAppDisposable), myAppDisposable);
}
}
public void tearDown() {
if (myAppDisposable != null) {
Disposer.dispose(myAppDisposable);
}
}
}