diff options
Diffstat (limited to 'plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java')
-rw-r--r-- | plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java | 103 |
1 files changed, 55 insertions, 48 deletions
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java index 602a6e8c460e..cfb4a935bc14 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java @@ -16,6 +16,9 @@ package org.jetbrains.idea.svn.commandLine; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Stack; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnUtil; import org.jetbrains.idea.svn.api.EventAction; @@ -43,17 +46,13 @@ public class UpdateOutputLineConverter { private final static String RECORDING_MERGE_INFO = "--- Recording mergeinfo"; private final static String UPDATING = "Updating"; - private final static String AT_REVISION = "At revision (\\d+)\\."; - private final static String UPDATED_TO_REVISION = "Updated to revision (\\d+)\\."; private final static String SKIPPED = "Skipped"; private final static String RESTORED = "Restored"; private final static String FETCHING_EXTERNAL = "Fetching external"; - private final static String EXTERNAL = "External at (\\d+)\\."; - private final static String UPDATED_EXTERNAL = "Updated external to revision (\\d+)\\."; - - private final static Pattern ourAtRevision = Pattern.compile(AT_REVISION); - private final static Pattern ourUpdatedToRevision = Pattern.compile(UPDATED_TO_REVISION); + + private final static Pattern ourAtRevision = Pattern.compile("At revision (\\d+)\\."); + private final static Pattern ourUpdatedToRevision = Pattern.compile("Updated to revision (\\d+)\\."); private final static Pattern ourCheckedOutRevision = Pattern.compile("Checked out revision (\\d+)\\."); // export from repository @@ -61,8 +60,8 @@ public class UpdateOutputLineConverter { // export from working copy private final static Pattern ourExportComplete = Pattern.compile("Export complete\\."); - private final static Pattern ourExternal = Pattern.compile(EXTERNAL); - private final static Pattern ourUpdatedExternal = Pattern.compile(UPDATED_EXTERNAL); + private final static Pattern ourExternal = Pattern.compile("External at (\\d+)\\."); + private final static Pattern ourUpdatedExternal = Pattern.compile("Updated external to revision (\\d+)\\."); private final static Pattern ourCheckedOutExternal = Pattern.compile("Checked out external at revision (\\d+)\\."); private final static Pattern[] ourCompletePatterns = @@ -70,15 +69,14 @@ public class UpdateOutputLineConverter { ourCheckedOutExternal, ourExportComplete}; private final File myBase; - private File myCurrentFile; + @NotNull private final Stack<File> myRootsUnderProcessing; public UpdateOutputLineConverter(File base) { myBase = base; - // checkout output does not have special line like "Updating '.'" on start - so set current file directly - // to correctly detect complete event - myCurrentFile = base; + myRootsUnderProcessing = ContainerUtil.newStack(); } + @Nullable public ProgressEvent convert(final String line) { // TODO: Add direct processing of "Summary of conflicts" lines at the end of "svn update" output (if there are conflicts). // TODO: Now it works ok because parseNormalLine could not determine necessary statuses from that and further lines @@ -87,35 +85,45 @@ public class UpdateOutputLineConverter { if (line.startsWith(MERGING) || line.startsWith(RECORDING_MERGE_INFO)) { return null; } else if (line.startsWith(UPDATING)) { - myCurrentFile = parseForPath(line); - return new ProgressEvent(myCurrentFile, -1, null, null, EventAction.UPDATE_NONE, null, null); + myRootsUnderProcessing.push(parseForPath(line)); + return createEvent(myRootsUnderProcessing.peek(), EventAction.UPDATE_NONE); } else if (line.startsWith(RESTORED)) { - myCurrentFile = parseForPath(line); - return new ProgressEvent(myCurrentFile, -1, null, null, EventAction.RESTORE, null, null); + return createEvent(parseForPath(line), EventAction.RESTORE); } else if (line.startsWith(SKIPPED)) { // called, for instance, when folder is not working copy - myCurrentFile = parseForPath(line); final String comment = parseComment(line); - return new ProgressEvent(myCurrentFile, -1, null, null, EventAction.SKIP, - comment == null ? null : SVNErrorMessage.create(SVNErrorCode.WC_OBSTRUCTED_UPDATE, comment), null); + return createEvent(parseForPath(line), -1, EventAction.SKIP, + comment == null ? null : SVNErrorMessage.create(SVNErrorCode.WC_OBSTRUCTED_UPDATE, comment)); } else if (line.startsWith(FETCHING_EXTERNAL)) { - myCurrentFile = parseForPath(line); - return new ProgressEvent(myCurrentFile, -1, null, null, EventAction.UPDATE_EXTERNAL, null, null); + myRootsUnderProcessing.push(parseForPath(line)); + return createEvent(myRootsUnderProcessing.peek(), EventAction.UPDATE_EXTERNAL); } - for (int i = 0; i < ourCompletePatterns.length; i++) { - final Pattern pattern = ourCompletePatterns[i]; + for (final Pattern pattern : ourCompletePatterns) { final long revision = matchAndGetRevision(pattern, line); if (revision != -1) { - // TODO: seems that myCurrentFile will not always be correct - complete update message could be right after complete externals update - // TODO: check this and use Stack instead - return new ProgressEvent(myCurrentFile, revision, null, null, EventAction.UPDATE_COMPLETED, null, null); + // checkout output does not have special line like "Updating '.'" on start - so stack could be empty and we should use myBase + File currentRoot = myRootsUnderProcessing.size() > 0 ? myRootsUnderProcessing.pop() : myBase; + return createEvent(currentRoot, revision, EventAction.UPDATE_COMPLETED, null); } } return parseNormalString(line); } + @NotNull + private static ProgressEvent createEvent(File file, @NotNull EventAction action) { + return createEvent(file, -1, action, null); + } + + @NotNull + private static ProgressEvent createEvent(File file, + long revision, + @NotNull EventAction action, + @Nullable SVNErrorMessage error) { + return new ProgressEvent(file, revision, null, null, action, error, null); + } + private final static Set<Character> ourActions = new HashSet<Character>(Arrays.asList(new Character[] {'A', 'D', 'U', 'C', 'G', 'E', 'R'})); @Nullable @@ -134,7 +142,7 @@ public class UpdateOutputLineConverter { final String path = line.substring(4).trim(); if (StringUtil.isEmptyOrSpaces(path)) return null; - final File file = createFile(path); + final File file = SvnUtil.resolvePath(myBase, path); if (StatusType.STATUS_OBSTRUCTED.equals(contentsStatus)) { // obstructed return new ProgressEvent(file, -1, contentsStatus, propertiesStatus, EventAction.UPDATE_SKIP_OBSTRUCTION, null, null); @@ -157,12 +165,7 @@ public class UpdateOutputLineConverter { return new ProgressEvent(file, -1, contentsStatus, propertiesStatus, action, null, null); } - private File createFile(String path) { - return SvnUtil.resolvePath(myBase, path); - } - - @Nullable - private long matchAndGetRevision(final Pattern pattern, final String line) { + private static long matchAndGetRevision(final Pattern pattern, final String line) { final Matcher matcher = pattern.matcher(line); if (matcher.matches()) { if (pattern == ourExportComplete) { @@ -181,22 +184,26 @@ public class UpdateOutputLineConverter { } @Nullable - private String parseComment(final String line) { - final int idx = line.lastIndexOf("--"); - if (idx != -1 && idx < (line.length() - 2)) { - return line.substring(idx + 2).trim(); - } - return null; + private static String parseComment(final String line) { + int index = line.lastIndexOf("--"); + + return index != -1 && index < line.length() - 2 ? line.substring(index + 2).trim() : null; } @Nullable - private File parseForPath(final String line) { - final int idx1 = line.indexOf('\''); - if (idx1 == -1) return null; - final int idx2 = line.indexOf('\'', idx1 + 1); - if (idx2 == -1) return null; - final String substring = line.substring(idx1 + 1, idx2); - if (".".equals(substring)) return myBase; - return createFile(substring); + private File parseForPath(@NotNull String line) { + File result = null; + int start = line.indexOf('\''); + + if (start != -1) { + int end = line.indexOf('\'', start + 1); + + if (end != -1) { + String path = line.substring(start + 1, end); + result = SvnUtil.resolvePath(myBase, path); + } + } + + return result; } } |