optimisation: way to get file boolean attributes in batch
[idea/community.git] / platform / platform-impl / src / com / intellij / openapi / vfs / impl / win32 / Win32Kernel.java
1 /*
2  * Copyright 2000-2011 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.openapi.vfs.impl.win32;
17
18 import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
19 import com.intellij.util.ArrayUtil;
20 import org.jetbrains.annotations.NotNull;
21 import org.jetbrains.annotations.Nullable;
22
23 import java.io.FileNotFoundException;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.Map;
27
28 /**
29  * @author Dmitry Avdeev
30  */
31 public class Win32Kernel {
32   public static final int FILE_ATTRIBUTE_READONLY = 0x0001;
33   public static final int FILE_ATTRIBUTE_HIDDEN = 0x0002;
34   public static final int FILE_ATTRIBUTE_DIRECTORY = 0x0010;
35   public static final int FILE_ATTRIBUTE_DEVICE = 0x0040;
36   public static final int FILE_ATTRIBUTE_REPARSE_POINT = 0x0400;
37
38   private final IdeaWin32 myKernel = new IdeaWin32();
39
40   private final Map<String, FileInfo> myCache = new HashMap<String, FileInfo>();
41
42   void clearCache() {
43     myCache.clear();
44   }
45
46   public String[] list(String absolutePath) {
47     FileInfo[] fileInfos = myKernel.listChildren(absolutePath.replace('/', '\\') + "\\*.*");
48     if (fileInfos == null) {
49       return ArrayUtil.EMPTY_STRING_ARRAY;
50     }
51     ArrayList<String> names = new ArrayList<String>(fileInfos.length);
52     for (FileInfo info : fileInfos) {
53       if (info.name.equals(".")) {
54         myCache.put(absolutePath, info);
55         continue;
56       }
57       if (info.name.equals("..")) {
58         continue;
59       }
60       myCache.put(absolutePath + "/" + info.name, info);
61       names.add(info.name);
62     }
63
64     return ArrayUtil.toStringArray(names);
65   }
66
67   public boolean exists(String path) {
68     return doGetInfo(path) != null;
69   }
70
71   public boolean isDirectory(String path) throws FileNotFoundException {
72     FileInfo data = getInfo(path);
73     return (data.attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
74   }
75
76   public boolean isWritable(String path) throws FileNotFoundException {
77     FileInfo fileInfo = getInfo(path);
78     myCache.remove(path);
79     return (fileInfo.attributes & FILE_ATTRIBUTE_READONLY) == 0;
80   }
81
82   public long getTimeStamp(String path) throws FileNotFoundException {
83     long timestamp = getInfo(path).timestamp;
84     return timestamp / 10000 - 11644473600000l;
85   }
86
87   public long getLength(String path) throws FileNotFoundException {
88     return getInfo(path).length;
89   }
90
91   private FileInfo getInfo(String path) throws FileNotFoundException {
92     FileInfo info = doGetInfo(path);
93     if (info == null) {
94       throw new FileNotFoundException(path);
95     }
96     return info;
97   }
98
99   @Nullable
100   private FileInfo doGetInfo(String path) {
101     FileInfo info = myCache.get(path);
102     if (info == null) {
103       info = myKernel.getInfo(path.replace('/', '\\'));
104       if (info == null) {
105         return null;
106       }
107       myCache.put(path, info);
108     }
109     return info;
110   }
111
112   @NewVirtualFileSystem.FileBooleanAttributes
113   public int getBooleanAttributes(@NotNull String path, @NewVirtualFileSystem.FileBooleanAttributes int flags) {
114     FileInfo info = doGetInfo(path);
115     int result = 0;
116     if ((flags & NewVirtualFileSystem.BA_EXISTS) != 0) {
117       result |= info == null ? 0 : NewVirtualFileSystem.BA_EXISTS;
118     }
119     if ((flags & NewVirtualFileSystem.BA_DIRECTORY) != 0) {
120       result |= info == null || (info.attributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ? 0 : NewVirtualFileSystem.BA_DIRECTORY;
121     }
122     if ((flags & NewVirtualFileSystem.BA_REGULAR) != 0) {
123       result |= info == null || (info.attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0 ? 0 : NewVirtualFileSystem.BA_REGULAR;
124     }
125     if ((flags & NewVirtualFileSystem.BA_HIDDEN) != 0) {
126       result |= info == null || (info.attributes & FILE_ATTRIBUTE_HIDDEN) == 0 ? 0 : NewVirtualFileSystem.BA_HIDDEN;
127     }
128     return result;
129   }
130 }