win 32 jni
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / vfs / newvfs / persistent / RefreshWorker.java
blob3cf55b766c6e692db3dee2b9c4f33ef69208a031
1 /*
2 * Copyright 2000-2009 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.
18 * @author max
20 package com.intellij.openapi.vfs.newvfs.persistent;
22 import com.intellij.openapi.util.SystemInfo;
23 import com.intellij.openapi.util.registry.Registry;
24 import com.intellij.openapi.vfs.LocalFileSystem;
25 import com.intellij.openapi.vfs.VfsUtil;
26 import com.intellij.openapi.vfs.VirtualFile;
27 import com.intellij.openapi.vfs.impl.win32.Win32LocalFileSystem;
28 import com.intellij.openapi.vfs.newvfs.ManagingFS;
29 import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
30 import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
31 import com.intellij.openapi.vfs.newvfs.events.*;
32 import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile;
33 import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
34 import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
35 import com.intellij.util.containers.Queue;
37 import java.util.*;
39 public class RefreshWorker {
40 private final VirtualFile myRefreshRoot;
41 private final boolean myIsRecursive;
42 private final Queue<VirtualFile> myRefreshQueue = new Queue<VirtualFile>(100);
44 private final List<VFileEvent> myEvents = new ArrayList<VFileEvent>();
46 public RefreshWorker(final VirtualFile refreshRoot, final boolean isRecursive) {
47 myRefreshRoot = refreshRoot;
48 myIsRecursive = isRecursive;
49 myRefreshQueue.addLast(refreshRoot);
52 public void scan() {
53 final NewVirtualFile root = (NewVirtualFile)myRefreshRoot;
54 NewVirtualFileSystem delegate = root.getFileSystem();
55 if (root.isDirty() && !delegate.exists(root)) {
56 scheduleDeletion(root);
57 root.markClean();
59 else {
60 if (delegate.getProtocol().equals(LocalFileSystem.PROTOCOL) &&
61 root.isDirectory() &&
62 Registry.is("filesystem.useNative")) {
64 if (SystemInfo.isWindows && Win32LocalFileSystem.isAvailable()) {
65 delegate = Win32LocalFileSystem.getWin32Instance();
69 final PersistentFS persistence = (PersistentFS)ManagingFS.getInstance();
71 while (!myRefreshQueue.isEmpty()) {
72 final VirtualFileSystemEntry file = (VirtualFileSystemEntry)myRefreshQueue.pullFirst();
73 if (!file.isDirty()) continue;
75 if (file.isDirectory()) {
76 VirtualDirectoryImpl dir = (VirtualDirectoryImpl)file;
77 final boolean fullSync = dir.allChildrenLoaded();
78 if (fullSync) {
79 Set<String> currentNames = new HashSet<String>(Arrays.asList(persistence.list(file)));
80 Set<String> uptodateNames = new HashSet<String>(Arrays.asList(VfsUtil.filterNames(delegate.list(file))));
82 Set<String> newNames = new HashSet<String>(uptodateNames);
83 newNames.removeAll(currentNames);
85 Set<String> deletedNames = new HashSet<String>(currentNames);
86 deletedNames.removeAll(uptodateNames);
88 for (String name : deletedNames) {
89 scheduleDeletion(file.findChild(name));
92 for (String name : newNames) {
93 boolean isDirectory = delegate.isDirectory(new FakeVirtualFile(file, name));
94 scheduleCreation(file, name, isDirectory);
97 for (VirtualFile child : file.getChildren()) {
98 if (!deletedNames.contains(child.getName())) {
99 scheduleChildRefresh(file, child, delegate);
103 else {
104 for (VirtualFile child : file.getCachedChildren()) {
105 if (delegate.exists(child)) {
106 scheduleChildRefresh(file, child, delegate);
108 else {
109 scheduleDeletion(child);
113 final List<String> names = dir.getSuspicousNames();
114 for (String name : names) {
115 if (name.length() == 0) continue;
117 final VirtualFile fake = new FakeVirtualFile(file, name);
118 if (delegate.exists(fake)) {
119 scheduleCreation(file, name, delegate.isDirectory(fake));
124 else {
125 long currentTimestamp = persistence.getTimeStamp(file);
126 long updtodateTimestamp = delegate.getTimeStamp(file);
128 if (currentTimestamp != updtodateTimestamp) {
129 scheduleUpdateContent(file);
133 boolean currentWritable = persistence.isWritable(file);
134 boolean uptodateWritable = delegate.isWritable(file);
136 if (currentWritable != uptodateWritable) {
137 scheduleWritableAttributeChange(file, currentWritable, uptodateWritable);
140 file.markClean();
145 private void scheduleChildRefresh(final VirtualFileSystemEntry file, final VirtualFile child, final NewVirtualFileSystem delegate) {
146 final boolean currentIsDirectory = child.isDirectory();
147 final boolean uptodateisDirectory = delegate.isDirectory(child);
148 if (currentIsDirectory != uptodateisDirectory) {
149 scheduleDeletion(child);
150 scheduleCreation(file, child.getName(), uptodateisDirectory);
152 else if (myIsRecursive || !currentIsDirectory) {
153 myRefreshQueue.addLast(child);
157 private void scheduleWritableAttributeChange(final VirtualFileSystemEntry file,
158 final boolean currentWritable,
159 final boolean uptodateWritable) {
160 myEvents.add(new VFilePropertyChangeEvent(null, file, VirtualFile.PROP_WRITABLE, currentWritable, uptodateWritable, true));
163 private void scheduleUpdateContent(final VirtualFileSystemEntry file) {
164 myEvents.add(new VFileContentChangeEvent(null, file, file.getModificationStamp(), -1, true));
167 private void scheduleCreation(final VirtualFileSystemEntry parent, final String childName, final boolean isDirectory) {
168 myEvents.add(new VFileCreateEvent(null, parent, childName, isDirectory, true));
171 private void scheduleDeletion(final VirtualFile file) {
172 if (file == null) return;
173 myEvents.add(new VFileDeleteEvent(null, file, true));
176 public List<VFileEvent> getEvents() {
177 return myEvents;