summaryrefslogtreecommitdiff
path: root/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/browserCache/SyntheticWorker.java
blob: 5d7c3c3c55c74938e4a22f7b58f5b8c47855fd09 (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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * 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.dialogs.browserCache;

import com.intellij.util.NotNullFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.api.NodeKind;
import org.jetbrains.idea.svn.browse.DirectoryEntry;
import org.jetbrains.idea.svn.checkin.CommitInfo;
import org.jetbrains.idea.svn.dialogs.RepositoryTreeNode;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;

import java.util.*;

public class SyntheticWorker {
  private final SvnRepositoryCache myCache;
  private final SVNURL myUrl;

  public SyntheticWorker(final SVNURL url) {
    myCache = SvnRepositoryCache.getInstance();
    myUrl = url;
  }

  public void removeSelf() {
    final String parentUrl;
    try {
      parentUrl = myUrl.removePathTail().toString();
    }
    catch (SVNException e) {
      return;
    }

    final List<DirectoryEntry> children = myCache.getChildren(parentUrl);
    if (children == null) {
      return;
    }
    for (Iterator<DirectoryEntry> iterator = children.iterator(); iterator.hasNext(); ) {
      final DirectoryEntry entry = iterator.next();
      if (myUrl.equals(entry.getUrl())) {
        iterator.remove();
      }
    }
    myCache.put(parentUrl, children);
  }

  public void addSyntheticChildToSelf(final SVNURL newUrl, final SVNURL repositoryUrl, final String name, final boolean isDir) {
    final String currentUrlAsString = myUrl.toString();

    final List<DirectoryEntry> children = myCache.getChildren(currentUrlAsString);
    if (children == null) {
      return;
    }
    children.add(createSyntheticEntry(newUrl, repositoryUrl, name, isDir));

    // TODO: Seems that just Set instead of List could be used in cache - so no sort() after add() will be required
    Collections.sort(children);
    myCache.put(currentUrlAsString, children);
  }

  public void copyTreeToSelf(final RepositoryTreeNode node) {
    try {
      node.doOnSubtree(new Adder(node.getURL().removePathTail().toString().length(), myUrl));
    }
    catch (SVNException e) {
      //
    }
  }

  public static void removeTreeOf(final RepositoryTreeNode node) {
    node.doOnSubtree(new Remover());
  }

  public static DirectoryEntry createSyntheticEntry(final SVNURL newUrl, final SVNURL repositoryUrl, final String name, final boolean isDir) {
    return new DirectoryEntry(newUrl, repositoryUrl, name, NodeKind.from(isDir), CommitInfo.EMPTY, null);
  }

  private static class Remover implements NotNullFunction<RepositoryTreeNode, Object> {
    private final SvnRepositoryCache myCache = SvnRepositoryCache.getInstance();

    @NotNull
    public Object fun(final RepositoryTreeNode repositoryTreeNode) {
      myCache.remove(repositoryTreeNode.getURL().toString());
      return Boolean.FALSE;
    }
  }

  private class Adder implements NotNullFunction<RepositoryTreeNode, Object> {
    private final int myOldPrefixLen;
    private final SVNURL myNewParentUrl;

    private Adder(final int oldPrefixLen, final SVNURL newParentUrl) {
      myOldPrefixLen = oldPrefixLen;
      myNewParentUrl = newParentUrl;
    }

    @NotNull
    public Object fun(final RepositoryTreeNode repositoryTreeNode) {
      final List<DirectoryEntry> children = myCache.getChildren(repositoryTreeNode.getURL().toString());
      if (children == null) {
        return Boolean.FALSE;
      }
      final List<DirectoryEntry> newChildren = new ArrayList<DirectoryEntry>(children.size());

      try {
        for (DirectoryEntry child : children) {
          newChildren.add(createSyntheticEntry(convertUrl(child.getUrl()), child.getRepositoryRoot(), child.getName(), child.isDirectory()));
        }
        myCache.put(convertUrl(repositoryTreeNode.getURL()).toString(), newChildren);
      }
      catch (SVNException e) {
        //
      }
      return Boolean.FALSE;
    }

    private SVNURL convertUrl(final SVNURL currentUrl) throws SVNException {
      return myNewParentUrl.appendPath(currentUrl.toString().substring(myOldPrefixLen), true);
    }
  }
}