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