[performance optimization] use VirtualFile.getNameSequence() instead of VirtualFile...
[idea/community.git] / platform / vcs-api / src / com / intellij / openapi / vcs / changes / IgnoredFileBean.java
1 /*
2  * Copyright 2000-2009 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
17 /*
18  * Created by IntelliJ IDEA.
19  * User: yole
20  * Date: 20.12.2006
21  * Time: 15:24:28
22  */
23 package com.intellij.openapi.vcs.changes;
24
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.util.Comparing;
27 import com.intellij.openapi.util.io.FileUtil;
28 import com.intellij.openapi.util.text.StringUtil;
29 import com.intellij.openapi.vfs.LocalFileSystem;
30 import com.intellij.openapi.vfs.VfsUtilCore;
31 import com.intellij.openapi.vfs.VirtualFile;
32 import com.intellij.openapi.vfs.newvfs.impl.NullVirtualFile;
33 import com.intellij.util.PatternUtil;
34 import org.jetbrains.annotations.Nullable;
35
36 import java.io.File;
37 import java.util.regex.Matcher;
38
39 public class IgnoredFileBean {
40   private final String myPath;
41   private final String myFilenameIfFile;
42   private final String myMask;
43   private final Matcher myMatcher;
44   private final IgnoreSettingsType myType;
45   private final Project myProject;
46   private volatile VirtualFile myCachedResolved;
47
48   IgnoredFileBean(String path, IgnoreSettingsType type, Project project) {
49     myPath = path;
50     myType = type;
51     if (IgnoreSettingsType.FILE.equals(type)) {
52       myFilenameIfFile = new File(path).getName();
53     }
54     else {
55       myFilenameIfFile = null;
56     }
57     myProject = project;
58     myMask = null;
59     myMatcher = null;
60   }
61
62   Project getProject() {
63     return myProject;
64   }
65
66   IgnoredFileBean(String mask) {
67     myType = IgnoreSettingsType.MASK;
68     myMask = mask;
69     if (mask == null) {
70       myMatcher = null;
71     }
72     else {
73       myMatcher = PatternUtil.fromMask(mask).matcher("");
74     }
75     myPath = null;
76     myFilenameIfFile = null;
77     myProject = null;
78   }
79
80   @Nullable
81   public String getPath() {
82     return myPath;
83   }
84
85   @Nullable
86   public String getMask() {
87     return myMask;
88   }
89
90   public IgnoreSettingsType getType() {
91     return myType;
92   }
93
94   @Override
95   public boolean equals(Object o) {
96     if (this == o) return true;
97     if (o == null || getClass() != o.getClass()) return false;
98
99     IgnoredFileBean that = (IgnoredFileBean)o;
100
101     if (myPath != null ? !myPath.equals(that.myPath) : that.myPath != null) return false;
102     if (myMask != null ? !myMask.equals(that.myMask) : that.myMask != null) return false;
103     if (myType != that.myType) return false;
104
105     return true;
106   }
107
108   @Override
109   public int hashCode() {
110     int result = myPath != null ? myPath.hashCode() : 0;
111     result = 31 * result + (myMask != null ? myMask.hashCode() : 0);
112     result = 31 * result + myType.hashCode();
113     return result;
114   }
115
116   public boolean matchesFile(VirtualFile file) {
117     if (myType == IgnoreSettingsType.MASK) {
118       myMatcher.reset(file.getName());
119       return myMatcher.matches();
120     }
121     else {
122       // quick check for 'file' == exact match pattern
123       if (IgnoreSettingsType.FILE.equals(myType) && !StringUtil.equals(myFilenameIfFile, file.getNameSequence())) return false;
124
125       VirtualFile selector = resolve();
126       if (Comparing.equal(selector, NullVirtualFile.INSTANCE)) return false;
127
128       if (myType == IgnoreSettingsType.FILE) {
129         return Comparing.equal(selector, file);
130       }
131       else {
132         if ("./".equals(myPath)) {
133           // special case for ignoring the project base dir (IDEADEV-16056)
134           return !file.isDirectory() && Comparing.equal(file.getParent(), selector);
135         }
136         return VfsUtilCore.isAncestor(selector, file, false);
137       }
138     }
139   }
140
141   private VirtualFile resolve() {
142     if (myCachedResolved == null) {
143       VirtualFile resolved = doResolve();
144       myCachedResolved = resolved != null ? resolved : NullVirtualFile.INSTANCE;
145     }
146
147     return myCachedResolved;
148   }
149
150   @Nullable
151   private VirtualFile doResolve() {
152     if (myProject == null || myProject.isDisposed()) {
153       return null;
154     }
155     VirtualFile baseDir = myProject.getBaseDir();
156
157     String path = FileUtil.toSystemIndependentName(myPath);
158     if (baseDir == null) {
159       return LocalFileSystem.getInstance().findFileByPath(path);
160     }
161
162     VirtualFile resolvedRelative = baseDir.findFileByRelativePath(path);
163     if (resolvedRelative != null) return resolvedRelative;
164
165     return LocalFileSystem.getInstance().findFileByPath(path);
166   }
167
168   public void resetCache() {
169     myCachedResolved = null;
170   }
171 }