Merge branch 'master' of git.labs.intellij.net:idea/community
[idea/community.git] / plugins / hg4idea / src / org / zmlx / hg4idea / command / HgStatusCommand.java
1 // Copyright 2008-2010 Victor Iacoban
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software distributed under
10 // the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11 // either express or implied. See the License for the specific language governing permissions and
12 // limitations under the License.
13 package org.zmlx.hg4idea.command;
14
15 import com.intellij.openapi.diagnostic.Logger;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.openapi.vfs.VirtualFile;
18 import org.apache.commons.lang.StringUtils;
19 import org.jetbrains.annotations.NotNull;
20 import org.jetbrains.annotations.Nullable;
21 import org.zmlx.hg4idea.HgFile;
22 import org.zmlx.hg4idea.HgRevisionNumber;
23
24 import java.io.File;
25 import java.nio.charset.Charset;
26 import java.util.*;
27
28 public class HgStatusCommand {
29
30   private static final Logger LOG = Logger.getInstance(HgStatusCommand.class.getName());
31
32   private static final int ITEM_COUNT = 3;
33   private static final int STATUS_INDEX = 0;
34
35   private final Project project;
36
37   private boolean includeAdded = true;
38   private boolean includeModified = true;
39   private boolean includeRemoved = true;
40   private boolean includeDeleted = true;
41   private boolean includeUnknown = true;
42   private boolean includeIgnored = true;
43   private boolean includeCopySource = true;
44   private HgRevisionNumber baseRevision;
45   private HgRevisionNumber targetRevision;
46
47   public HgStatusCommand(Project project) {
48     this.project = project;
49   }
50
51   public void setIncludeAdded(boolean includeAdded) {
52     this.includeAdded = includeAdded;
53   }
54
55   public void setIncludeModified(boolean includeModified) {
56     this.includeModified = includeModified;
57   }
58
59   public void setIncludeRemoved(boolean includeRemoved) {
60     this.includeRemoved = includeRemoved;
61   }
62
63   public void setIncludeDeleted(boolean includeDeleted) {
64     this.includeDeleted = includeDeleted;
65   }
66
67   public void setIncludeUnknown(boolean includeUnknown) {
68     this.includeUnknown = includeUnknown;
69   }
70
71   public void setIncludeIgnored(boolean includeIgnored) {
72     this.includeIgnored = includeIgnored;
73   }
74
75   public void setIncludeCopySource(boolean includeCopySource) {
76     this.includeCopySource = includeCopySource;
77   }
78
79   public void setBaseRevision(HgRevisionNumber base) {
80     baseRevision = base;
81   }
82
83   public void setTargetRevision(HgRevisionNumber target) {
84     targetRevision = target;
85   }
86
87   public Set<HgChange> execute(VirtualFile repo) {
88     return doExecute(repo, null);
89   }
90
91   @Nullable
92   public HgChange execute(VirtualFile repo, @NotNull String file) {
93     Set<HgChange> changes = doExecute(repo, file);
94     return changes.isEmpty() ? null : changes.iterator().next();
95   }
96
97   private Set<HgChange> doExecute(VirtualFile repo, String file) {
98     if (repo == null) {
99       return Collections.emptySet();
100     }
101
102     HgCommandService service = HgCommandService.getInstance(project);
103
104     List<String> arguments = new LinkedList<String>();
105     if (includeAdded) {
106       arguments.add("--added");
107     }
108     if (includeModified) {
109       arguments.add("--modified");
110     }
111     if (includeRemoved) {
112       arguments.add("--removed");
113     }
114     if (includeDeleted) {
115       arguments.add("--deleted");
116     }
117     if (includeUnknown) {
118       arguments.add("--unknown");
119     }
120     if (includeIgnored) {
121       arguments.add("--ignored");
122     }
123     if (includeCopySource) {
124       arguments.add("--copies");
125     }
126     if (baseRevision != null) {
127       arguments.add("--rev");
128       arguments.add(baseRevision.getChangeset());
129       if (targetRevision != null) {
130         arguments.add("--rev");
131         arguments.add(targetRevision.getChangeset());
132       }
133     }
134
135     if (file != null) {
136       arguments.add(file);
137     }
138
139     HgCommandResult result = service.execute(repo, HgCommandService.DEFAULT_OPTIONS, "status", arguments, Charset.defaultCharset(), true);
140     Set<HgChange> changes = new HashSet<HgChange>();
141     HgChange previous = null;
142     if (result == null) {
143       return changes;
144     }
145     for (String line : result.getOutputLines()) {
146       if (StringUtils.isBlank(line) || line.length() < ITEM_COUNT) {
147         LOG.warn("Unexpected line in status '" + line + '\'');
148         continue;
149       }
150       HgFileStatusEnum status = HgFileStatusEnum.valueOf(line.charAt(STATUS_INDEX));
151       File ioFile = new File(repo.getPath(), line.substring(2));
152       if (HgFileStatusEnum.COPY == status && previous != null
153         && previous.getStatus() == HgFileStatusEnum.ADDED) {
154         previous.setStatus(HgFileStatusEnum.COPY);
155         previous.setBeforeFile(new HgFile(repo, ioFile));
156         previous = null;
157       } else {
158         previous = new HgChange(new HgFile(repo, ioFile), status);
159         changes.add(previous);
160       }
161     }
162     return changes;
163   }
164 }