summaryrefslogtreecommitdiff
path: root/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnScopeZipper.java
blob: d4c98221a5677dcdf09370f9516455c1bb21471a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * Copyright 2000-2009 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 org.jetbrains.idea.svn;

import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.changes.VcsDirtyScope;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SvnScopeZipper implements Runnable {

  @NotNull private final VcsDirtyScope myIn;
  @NotNull private final List<FilePath> myRecursiveDirs;
  // instead of set and heavy equals of file path
  @NotNull private final Map<String, MyDirNonRecursive> myNonRecursiveDirs;

  public SvnScopeZipper(@NotNull VcsDirtyScope in) {
    myIn = in;
    myRecursiveDirs = ContainerUtil.newArrayList(in.getRecursivelyDirtyDirectories());
    myNonRecursiveDirs = ContainerUtil.newHashMap();
  }

  public void run() {
    // if put directly into dirty scope, to access a copy will be created every time
    final Set<FilePath> files = myIn.getDirtyFilesNoExpand();

    for (FilePath file : files) {
      if (file.isDirectory()) {
        final VirtualFile vFile = file.getVirtualFile();
        // todo take care about this 'not valid' - right now keeping things as they used to be
        final MyDirNonRecursive me = createOrGet(file);
        if (vFile != null && vFile.isValid()) {
          for (VirtualFile child : vFile.getChildren()) {
            me.add(new FilePathImpl(child));
          }
        }
      }
      else {
        final FilePath parent = file.getParentPath();
        if (parent != null) {
          final MyDirNonRecursive item = createOrGet(parent);
          item.add(file);
        }
      }
    }
  }

  @NotNull
  private MyDirNonRecursive createOrGet(@NotNull FilePath parent) {
    String key = getKey(parent);
    MyDirNonRecursive result = myNonRecursiveDirs.get(key);

    if (result == null) {
      result = new MyDirNonRecursive(parent);
      myNonRecursiveDirs.put(key, result);
    }

    return result;
  }

  @NotNull
  public List<FilePath> getRecursiveDirs() {
    return myRecursiveDirs;
  }

  @NotNull
  public Map<String, MyDirNonRecursive> getNonRecursiveDirs() {
    return myNonRecursiveDirs;
  }

  public static String getKey(@NotNull FilePath path) {
    return path.getPresentableUrl();
  }

  static class MyDirNonRecursive {

    @NotNull private final FilePath myDir;
    // instead of set and heavy equals of file path
    @NotNull private final Map<String, FilePath> myChildren;

    private MyDirNonRecursive(@NotNull FilePath dir) {
      myDir = dir;
      myChildren = ContainerUtil.newHashMap();
    }

    public void add(@NotNull FilePath path) {
      myChildren.put(getKey(path), path);
    }

    @NotNull
    public Collection<FilePath> getChildrenList() {
      return myChildren.values();
    }

    @NotNull
    public FilePath getDir() {
      return myDir;
    }
  }
}