diff options
Diffstat (limited to 'plugins/svn4idea/src/org/jetbrains/idea/svn/annotate')
7 files changed, 220 insertions, 284 deletions
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java index df30cfd89ae2..90be057af431 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java @@ -4,8 +4,7 @@ import com.intellij.openapi.vcs.VcsException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.api.SvnClient; -import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler; -import org.tmatesoft.svn.core.wc.SVNDiffOptions; +import org.jetbrains.idea.svn.diff.DiffOptions; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; @@ -19,6 +18,6 @@ public interface AnnotateClient extends SvnClient { @NotNull SVNRevision endRevision, @Nullable SVNRevision pegRevision, boolean includeMergedRevisions, - @Nullable SVNDiffOptions diffOptions, - @Nullable ISVNAnnotateHandler handler) throws VcsException; + @Nullable DiffOptions diffOptions, + @Nullable AnnotationConsumer handler) throws VcsException; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotationConsumer.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotationConsumer.java new file mode 100644 index 000000000000..8d33be224b99 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotationConsumer.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2014 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.annotate; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.checkin.CommitInfo; +import org.tmatesoft.svn.core.SVNException; + +/** + * @author Konstantin Kolosovsky. + */ +public interface AnnotationConsumer { + + void consume(int lineNumber, @NotNull CommitInfo info, @Nullable CommitInfo mergeInfo) throws SVNException; +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/BaseSvnFileAnnotation.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/BaseSvnFileAnnotation.java index f4fa9f950a32..00a529e11b4d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/BaseSvnFileAnnotation.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/BaseSvnFileAnnotation.java @@ -19,6 +19,7 @@ import com.intellij.openapi.vcs.VcsKey; import com.intellij.openapi.vcs.annotate.*; import com.intellij.openapi.vcs.history.VcsFileRevision; import com.intellij.openapi.vcs.history.VcsRevisionNumber; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.DateFormatUtil; import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NotNull; @@ -27,6 +28,7 @@ import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnConfiguration; import org.jetbrains.idea.svn.SvnRevisionNumber; import org.jetbrains.idea.svn.SvnVcs; +import org.jetbrains.idea.svn.checkin.CommitInfo; import org.jetbrains.idea.svn.history.SvnFileRevision; import org.tmatesoft.svn.core.wc.SVNRevision; @@ -46,27 +48,19 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { protected final SvnVcs myVcs; private final Map<Long, SvnFileRevision> myRevisionMap = new HashMap<Long, SvnFileRevision>(); - private final LineAnnotationAspect DATE_ASPECT = new SvnAnnotationAspect(SvnAnnotationAspect.DATE, true) { - public String getValue(int lineNumber) { - if (myInfos.size() <= lineNumber || lineNumber < 0) { - return ""; - } - else { - final LineInfo lineInfo = myInfos.get(lineNumber); - return (lineInfo == null) ? "" : DateFormatUtil.formatPrettyDate(lineInfo.getDate()); - } + private final LineAnnotationAspect DATE_ASPECT = new SvnAnnotationAspect(LineAnnotationAspect.DATE, true) { + + @Override + public String getValue(@NotNull CommitInfo info) { + return DateFormatUtil.formatPrettyDate(info.getDate()); } }; - private final LineAnnotationAspect REVISION_ASPECT = new SvnAnnotationAspect(SvnAnnotationAspect.REVISION, false) { - public String getValue(int lineNumber) { - if (myInfos.size() <= lineNumber || lineNumber < 0) { - return ""; - } - else { - final long revision = getRevision(lineNumber); - return (revision == -1) ? "" : String.valueOf(revision); - } + private final LineAnnotationAspect REVISION_ASPECT = new SvnAnnotationAspect(LineAnnotationAspect.REVISION, false) { + + @Override + public String getValue(@NotNull CommitInfo info) { + return String.valueOf(info.getRevision()); } }; @@ -84,31 +78,25 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { @Override public String getTooltipText(int lineNumber) { - if (myInfos.size() <= lineNumber || lineNumber < 0) { - return ""; - } - final LineInfo info = myInfos.get(lineNumber); + // TODO: Check what is the difference in returning "" or null + if (!myInfos.isValid(lineNumber)) return ""; + + CommitInfo info = myInfos.get(lineNumber); if (info == null) return null; - SvnFileRevision svnRevision = myRevisionMap.get(info.getRevision()); - if (svnRevision != null) { - final String tooltip = "Revision " + info.getRevision() + ": " + svnRevision.getCommitMessage(); - return XmlStringUtil.escapeString(tooltip); - } - return ""; + + SvnFileRevision revision = myRevisionMap.get(info.getRevision()); + return revision != null ? XmlStringUtil.escapeString("Revision " + info.getRevision() + ": " + revision.getCommitMessage()) : ""; } }; - private final LineAnnotationAspect AUTHOR_ASPECT = new SvnAnnotationAspect(SvnAnnotationAspect.AUTHOR, true) { - public String getValue(int lineNumber) { - if (myInfos.size() <= lineNumber || lineNumber < 0) { - return ""; - } - else { - final LineInfo lineInfo = myInfos.get(lineNumber); - return (lineInfo == null) ? "" : lineInfo.getAuthor(); - } + private final LineAnnotationAspect AUTHOR_ASPECT = new SvnAnnotationAspect(LineAnnotationAspect.AUTHOR, true) { + + @Override + public String getValue(@NotNull CommitInfo info) { + return info.getAuthor(); } }; + private final SvnConfiguration myConfiguration; private boolean myShowMergeSources; // null if full annotation @@ -118,10 +106,6 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { myRevisionMap.put(revision, svnRevision); } - public void clearRevisions() { - myRevisionMap.clear(); - } - public SvnFileRevision getRevision(final long revision) { return myRevisionMap.get(revision); } @@ -134,30 +118,6 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { return myFirstRevisionNumber; } - static class LineInfo { - private final Date myDate; - private final long myRevision; - private final String myAuthor; - - public LineInfo(final Date date, final long revision, final String author) { - myDate = date; - myRevision = revision; - myAuthor = author; - } - - public Date getDate() { - return myDate; - } - - public long getRevision() { - return myRevision; - } - - public String getAuthor() { - return myAuthor; - } - } - public BaseSvnFileAnnotation(final SvnVcs vcs, final String contents, final VcsRevisionNumber baseRevision) { super(vcs.getProject()); myVcs = vcs; @@ -174,18 +134,14 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { } public String getToolTip(final int lineNumber) { - if (myInfos.size() <= lineNumber || lineNumber < 0) { - return ""; - } - final LineInfo info = myInfos.get(lineNumber); + final CommitInfo info = myInfos.getOrNull(lineNumber); if (info == null) return ""; - SvnFileRevision svnRevision = myRevisionMap.get(info.getRevision()); - if (svnRevision != null) { - if (myInfos.getAnnotationSource(lineNumber).showMerged()) { - return "Merge source revision " + info.getRevision() + ": " + svnRevision.getCommitMessage(); - } else { - return "Revision " + info.getRevision() + ": " + svnRevision.getCommitMessage(); - } + + SvnFileRevision revision = myRevisionMap.get(info.getRevision()); + if (revision != null) { + String prefix = myInfos.getAnnotationSource(lineNumber).showMerged() ? "Merge source revision" : "Revision"; + + return prefix + " " + info.getRevision() + ": " + revision.getCommitMessage(); } return ""; } @@ -194,53 +150,35 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { return myContents; } - public void setLineInfo(final int lineNumber, final Date date, final long revision, final String author, - @Nullable final Date mergeDate, final long mergeRevision, @Nullable final String mergeAuthor) { - myInfos.appendNumberedLineInfo(lineNumber, date, revision, author, mergeDate, mergeRevision, mergeAuthor); - } - - public void appendLineInfo(final Date date, final long revision, final String author, - @Nullable final Date mergeDate, final long mergeRevision, @Nullable final String mergeAuthor) { - myInfos.appendNumberedLineInfo(date, revision, author, mergeDate, mergeRevision, mergeAuthor); + public void setLineInfo(int lineNumber, @NotNull CommitInfo info, @Nullable CommitInfo mergeInfo) { + myInfos.appendNumberedLineInfo(lineNumber, info, mergeInfo); } @Nullable public VcsRevisionNumber originalRevision(final int lineNumber) { - if (myInfos.size() <= lineNumber || lineNumber < 0) { - return null; - } - final SvnFileRevision revision = myRevisionMap.get(myInfos.originalRevision(lineNumber)); - return revision == null ? null : revision.getRevisionNumber(); + SvnFileRevision revision = myInfos.isValid(lineNumber) ? myRevisionMap.get(myInfos.originalRevision(lineNumber)) : null; + + return revision != null ? revision.getRevisionNumber() : null; } public VcsRevisionNumber getLineRevisionNumber(final int lineNumber) { - if (myInfos.size() <= lineNumber || lineNumber < 0) { - return null; - } - final LineInfo info = myInfos.get(lineNumber); - if (info == null) return null; - final long revision = info.getRevision(); - if (revision >= 0) { - return new SvnRevisionNumber(SVNRevision.create(revision)); - } - return null; + CommitInfo info = myInfos.getOrNull(lineNumber); + + return info != null && info.getRevision() >= 0 ? new SvnRevisionNumber(SVNRevision.create(info.getRevision())) : null; } @Override public Date getLineDate(int lineNumber) { - if (myInfos.size() <= lineNumber || lineNumber < 0) { - return null; - } - final LineInfo info = myInfos.get(lineNumber); - if (info == null) return null; - return info.getDate(); + CommitInfo info = myInfos.getOrNull(lineNumber); + + return info != null ? info.getDate() : null; } public List<VcsFileRevision> getRevisions() { final List<VcsFileRevision> result = new ArrayList<VcsFileRevision>(myRevisionMap.values()); Collections.sort(result, new Comparator<VcsFileRevision>() { public int compare(final VcsFileRevision o1, final VcsFileRevision o2) { - return -1 * o1.getRevisionNumber().compareTo(o2.getRevisionNumber()); + return o2.getRevisionNumber().compareTo(o1.getRevisionNumber()); } }); return result; @@ -250,10 +188,6 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { return ! myRevisionMap.isEmpty(); } - public int getNumLines() { - return myInfos.size(); - } - @Nullable public AnnotationSourceSwitcher getAnnotationSourceSwitcher() { if (! myShowMergeSources) return null; @@ -285,7 +219,7 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { @Override public int getLineCount() { - return getNumLines(); + return myInfos.size(); } @Override @@ -294,44 +228,52 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { } private abstract class SvnAnnotationAspect extends LineAnnotationAspectAdapter { + public SvnAnnotationAspect(String id, boolean showByDefault) { super(id, showByDefault); } protected long getRevision(final int lineNum) { - final LineInfo lineInfo = myInfos.get(lineNum); + final CommitInfo lineInfo = myInfos.get(lineNum); return (lineInfo == null) ? -1 : lineInfo.getRevision(); } @Override protected void showAffectedPaths(int lineNum) { - if (lineNum >= 0 && lineNum < myInfos.size()) { + if (myInfos.isValid(lineNum)) { final long revision = getRevision(lineNum); if (revision >= 0) { showAllAffectedPaths(new SvnRevisionNumber(SVNRevision.create(revision))); } } } + + @Override + public String getValue(int lineNumber) { + CommitInfo info = myInfos.getOrNull(lineNumber); + + return info == null ? "" : getValue(info); + } + + public String getValue(@NotNull CommitInfo info) { + return ""; + } } protected abstract void showAllAffectedPaths(SvnRevisionNumber number); private static class MyPartiallyCreatedInfos { private boolean myShowMergeSource; - private final Map<Integer, LineInfo> myMappedLineInfo; - private final Map<Integer, LineInfo> myMergeSourceInfos; + private final Map<Integer, CommitInfo> myMappedLineInfo; + private final Map<Integer, CommitInfo> myMergeSourceInfos; private int myMaxIdx; private MyPartiallyCreatedInfos() { - myMergeSourceInfos = new HashMap<Integer, LineInfo>(); - myMappedLineInfo = new HashMap<Integer, LineInfo>(); + myMergeSourceInfos = ContainerUtil.newHashMap(); + myMappedLineInfo = ContainerUtil.newHashMap(); myMaxIdx = 0; } - boolean isShowMergeSource() { - return myShowMergeSource; - } - void setShowMergeSource(boolean showMergeSource) { myShowMergeSource = showMergeSource; } @@ -340,25 +282,18 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { return myMaxIdx + 1; } - void appendNumberedLineInfo(final Date date, final long revision, final String author, - @Nullable final Date mergeDate, final long mergeRevision, @Nullable final String mergeAuthor) { - appendNumberedLineInfo(myMaxIdx + 1, date, revision, author, mergeDate, mergeRevision, mergeAuthor); - } - - void appendNumberedLineInfo(final int lineNumber, final Date date, final long revision, final String author, - @Nullable final Date mergeDate, final long mergeRevision, @Nullable final String mergeAuthor) { - if (date == null) return; + void appendNumberedLineInfo(final int lineNumber, @NotNull CommitInfo info, @Nullable CommitInfo mergeInfo) { if (myMappedLineInfo.get(lineNumber) != null) return; myMaxIdx = (myMaxIdx < lineNumber) ? lineNumber : myMaxIdx; - myMappedLineInfo.put(lineNumber, new LineInfo(date, revision, author)); - if (mergeDate != null) { - myMergeSourceInfos.put(lineNumber, new LineInfo(mergeDate, mergeRevision, mergeAuthor)); + myMappedLineInfo.put(lineNumber, info); + if (mergeInfo != null) { + myMergeSourceInfos.put(lineNumber, mergeInfo); } } - LineInfo get(final int idx) { + CommitInfo get(final int idx) { if (myShowMergeSource) { - final LineInfo lineInfo = myMergeSourceInfos.get(idx); + final CommitInfo lineInfo = myMergeSourceInfos.get(idx); if (lineInfo != null) { return lineInfo; } @@ -366,14 +301,23 @@ public abstract class BaseSvnFileAnnotation extends FileAnnotation { return myMappedLineInfo.get(idx); } + @Nullable + CommitInfo getOrNull(int lineNumber) { + return isValid(lineNumber) ? get(lineNumber) : null; + } + + private boolean isValid(int lineNumber) { + return lineNumber >= 0 && lineNumber < size(); + } + AnnotationSource getAnnotationSource(final int line) { return myShowMergeSource ? AnnotationSource.getInstance(myMergeSourceInfos.containsKey(line)) : AnnotationSource.LOCAL; } public long originalRevision(final int line) { - if (line >= size()) return -1; - final LineInfo lineInfo = myMappedLineInfo.get(line); - return lineInfo == null ? -1 : lineInfo.getRevision(); + CommitInfo info = line < size() ? myMappedLineInfo.get(line) : null; + + return info == null ? -1 : info.getRevision(); } public boolean mergeSourceAvailable(int lineNumber) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java index 5cb18a35fc5c..b48f14a41779 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java @@ -4,12 +4,12 @@ import com.intellij.openapi.vcs.VcsException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.api.BaseSvnClient; +import org.jetbrains.idea.svn.checkin.CommitInfo; import org.jetbrains.idea.svn.commandLine.CommandExecutor; import org.jetbrains.idea.svn.commandLine.CommandUtil; import org.jetbrains.idea.svn.commandLine.SvnCommandName; +import org.jetbrains.idea.svn.diff.DiffOptions; import org.tmatesoft.svn.core.SVNException; -import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler; -import org.tmatesoft.svn.core.wc.SVNDiffOptions; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; @@ -18,7 +18,6 @@ import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import java.util.ArrayList; -import java.util.Date; import java.util.List; /** @@ -32,8 +31,8 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { @NotNull SVNRevision endRevision, @Nullable SVNRevision pegRevision, boolean includeMergedRevisions, - @Nullable SVNDiffOptions diffOptions, - @Nullable final ISVNAnnotateHandler handler) throws VcsException { + @Nullable DiffOptions diffOptions, + @Nullable final AnnotationConsumer handler) throws VcsException { List<String> parameters = new ArrayList<String>(); CommandUtil.put(parameters, target.getPathOrUrlString(), pegRevision); parameters.add("--revision"); @@ -47,7 +46,7 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { parseOutput(command.getOutput(), handler); } - public void parseOutput(@NotNull String output, @Nullable ISVNAnnotateHandler handler) throws VcsException { + public void parseOutput(@NotNull String output, @Nullable AnnotationConsumer handler) throws VcsException { try { BlameInfo info = CommandUtil.parse(output, BlameInfo.class); @@ -65,12 +64,11 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { } } - private static void invokeHandler(ISVNAnnotateHandler handler, LineEntry entry) throws SVNException { - // line numbers in our api start from 0 - not from 1 like in svn output - // "line" value is not used in handlers - so null is passed - handler - .handleLine(entry.date(), entry.revision(), entry.author(), null, entry.mergedDate(), entry.mergedRevision(), entry.mergedAuthor(), - entry.mergedPath(), entry.lineNumber - 1); + private static void invokeHandler(@NotNull AnnotationConsumer handler, @NotNull LineEntry entry) throws SVNException { + if (entry.commit != null) { + // line numbers in our api start from 0 - not from 1 like in svn output + handler.consume(entry.lineNumber - 1, entry.commit.build(), entry.mergedCommit()); + } } @XmlRootElement(name = "blame") @@ -91,70 +89,15 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { @XmlAttribute(name = "line-number") public int lineNumber; - @XmlElement(name = "commit") - public CommitEntry commit; + public CommitInfo.Builder commit; @XmlElement(name = "merged") public MergedEntry merged; - public long revision() { - return revision(commit); - } - - @Nullable - public String author() { - return author(commit); - } - - @Nullable - public Date date() { - return date(commit); - } - - @Nullable - public String mergedPath() { - return merged != null ? merged.path : null; - } - - public long mergedRevision() { - return merged != null ? revision(merged.commit) : 0; - } - - @Nullable - public String mergedAuthor() { - return merged != null ? author(merged.commit) : null; - } - - @Nullable - public Date mergedDate() { - return merged != null ? date(merged.commit) : null; - } - - private static long revision(@Nullable CommitEntry commit) { - return commit != null ? commit.revision : 0; - } - @Nullable - private static String author(@Nullable CommitEntry commit) { - return commit != null ? commit.author : null; + public CommitInfo mergedCommit() { + return merged != null && merged.commit != null ? merged.commit.build() : null; } - - @Nullable - private static Date date(@Nullable CommitEntry commit) { - return commit != null ? commit.date : null; - } - } - - public static class CommitEntry { - - @XmlAttribute(name = "revision") - public long revision; - - @XmlElement(name = "author") - public String author; - - @XmlElement(name = "date") - public Date date; } public static class MergedEntry { @@ -162,7 +105,6 @@ public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient { @XmlAttribute(name = "path") public String path; - @XmlElement(name = "commit") - public CommitEntry commit; + public CommitInfo.Builder commit; } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java index c51f4dbcdaa3..a615fd4e3afa 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java @@ -35,11 +35,15 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.*; -import org.jetbrains.idea.svn.history.HistoryClient; -import org.jetbrains.idea.svn.history.SvnChangeList; -import org.jetbrains.idea.svn.history.SvnFileRevision; -import org.tmatesoft.svn.core.*; -import org.tmatesoft.svn.core.wc.*; +import org.jetbrains.idea.svn.checkin.CommitInfo; +import org.jetbrains.idea.svn.diff.DiffOptions; +import org.jetbrains.idea.svn.history.*; +import org.jetbrains.idea.svn.info.Info; +import org.tmatesoft.svn.core.SVNErrorCode; +import org.tmatesoft.svn.core.SVNErrorMessage; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; @@ -86,7 +90,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn public void run() { final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); final File ioFile = new File(file.getPath()).getAbsoluteFile(); - SVNInfo info = null; + Info info = null; try { final String contents; @@ -116,7 +120,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn } // ignore mime type=true : IDEA-19562 - final ISVNAnnotateHandler annotateHandler = createAnnotationHandler(progress, result); + final AnnotationConsumer annotateHandler = createAnnotationHandler(progress, result); final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).isShowMergeSourcesInAnnotate() && SvnUtil.checkRepositoryVersion15(myVcs, url); @@ -166,7 +170,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn } private void handleSvnException(File ioFile, - SVNInfo info, + Info info, SVNException e, VirtualFile file, VcsFileRevision revision, @@ -221,7 +225,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn private SvnRemoteFileAnnotation annotateNonExisting(Pair<SvnChangeList, FilePath> pair, VcsFileRevision revision, - SVNInfo info, + Info info, Charset charset, final VirtualFile current) throws VcsException, SVNException, IOException { final File wasFile = pair.getSecond().getIOFile(); final File root = getCommonAncestor(wasFile, info.getFile()); @@ -231,7 +235,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn final String relativePath = FileUtil.getRelativePath(root.getPath(), wasFile.getPath(), File.separatorChar); if (relativePath == null) throw new VcsException("Can not find relative path for " + wasFile.getPath() + "@" + revision.getRevisionNumber().asString()); - SVNInfo wcRootInfo = myVcs.getInfo(root); + Info wcRootInfo = myVcs.getInfo(root); if (wcRootInfo == null || wcRootInfo.getURL() == null) { throw new VcsException("Can not find relative path for " + wasFile.getPath() + "@" + revision.getRevisionNumber().asString()); } @@ -244,9 +248,8 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn final SVNRevision svnRevision = ((SvnRevisionNumber)revision.getRevisionNumber()).getRevision(); byte[] data = SvnUtil.getFileContents(myVcs, SvnTarget.fromURL(wasUrl), svnRevision, svnRevision); final String contents = LoadTextUtil.getTextByBinaryPresentation(data, charset == null ? CharsetToolkit.UTF8_CHARSET : charset).toString(); - final SvnRemoteFileAnnotation result = new SvnRemoteFileAnnotation(myVcs, contents, revision.getRevisionNumber(), pair.getFirst(), - pair.getSecond().getPath(), current); - final ISVNAnnotateHandler annotateHandler = createAnnotationHandler(ProgressManager.getInstance().getProgressIndicator(), result); + final SvnRemoteFileAnnotation result = new SvnRemoteFileAnnotation(myVcs, contents, revision.getRevisionNumber(), current); + final AnnotationConsumer annotateHandler = createAnnotationHandler(ProgressManager.getInstance().getProgressIndicator(), result); final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).isShowMergeSourcesInAnnotate() && SvnUtil.checkRepositoryVersion15(myVcs, wasUrl.toString()); @@ -256,45 +259,18 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn return result; } - private ISVNAnnotateHandler createAnnotationHandler(final ProgressIndicator progress, final BaseSvnFileAnnotation result) { - return new ISVNAnnotateHandler() { - public void handleLine(Date date, long revision, String author, String line) { - if (progress != null) { - progress.checkCanceled(); - } - result.appendLineInfo(date, revision, author, null, -1, null); - } - - public void handleLine(final Date date, - final long revision, - final String author, - final String line, - final Date mergedDate, - final long mergedRevision, - final String mergedAuthor, - final String mergedPath, - final int lineNumber) throws SVNException { - if (progress != null) { - progress.checkCanceled(); - } - if (revision == -1) return; - if ((mergedDate != null) && (revision > mergedRevision)) { - // !!! merged date = date of merge, i.e. date -> date of original change etc. - result.setLineInfo(lineNumber, date, revision, author, mergedDate, mergedRevision, mergedAuthor); - } else { - result.setLineInfo(lineNumber, date, revision, author, null, -1, null); - } - } + @NotNull + private static AnnotationConsumer createAnnotationHandler(@Nullable final ProgressIndicator progress, + @NotNull final BaseSvnFileAnnotation result) { + return new AnnotationConsumer() { - public boolean handleRevision(final Date date, final long revision, final String author, final File contents) - throws SVNException { + @Override + public void consume(int lineNumber, @NotNull CommitInfo info, @Nullable CommitInfo mergeInfo) throws SVNException { if (progress != null) { progress.checkCanceled(); } - return false; - } - public void handleEOF() { + result.setLineInfo(lineNumber, info, mergeInfo != null && info.getRevision() > mergeInfo.getRevision() ? mergeInfo : null); } }; } @@ -307,7 +283,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn if (annotationSourceSwitcher != null) { annotationSourceSwitcher.switchTo(AnnotationSource.LOCAL); } - final int size = svnFileAnnotation.getNumLines(); + final int size = svnFileAnnotation.getLineCount(); final VcsUsualLineAnnotationData lineAnnotationData = new VcsUsualLineAnnotationData(size); for (int i = 0; i < size; i++) { @@ -356,17 +332,15 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn for (int i = 0; i < basicAnnotation.getNumLines(); i++) { final VcsRevisionNumber revision = basicAnnotation.getRevision(i); final VcsRevisionNumber mergedData = data == null ? null : data.getRevision(i); - final VcsFileRevision fileRevision = historyAsMap.get(revision); + final SvnFileRevision fileRevision = (SvnFileRevision)historyAsMap.get(revision); if (fileRevision == null) return null; + if (mergedData == null) { - annotation.setLineInfo(i, fileRevision.getRevisionDate(), ((SvnRevisionNumber) revision).getRevision().getNumber(), - fileRevision.getAuthor(), null, -1, null); + annotation.setLineInfo(i, fileRevision.getCommitInfo(), null); } else { - final VcsFileRevision mergedRevision = cachedOtherRevisions.get(mergedData); + final SvnFileRevision mergedRevision = (SvnFileRevision)cachedOtherRevisions.get(mergedData); if (mergedRevision == null) return null; - annotation.setLineInfo(i, fileRevision.getRevisionDate(), ((SvnRevisionNumber) revision).getRevision().getNumber(), - fileRevision.getAuthor(), mergedRevision.getRevisionDate(), - ((SvnRevisionNumber) mergedRevision.getRevisionNumber()).getRevision().getNumber(), mergedRevision.getAuthor()); + annotation.setLineInfo(i, fileRevision.getCommitInfo(), mergedRevision.getCommitInfo()); } } if (vcsAnnotation.getFirstRevision() != null) { @@ -453,8 +427,9 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn private void doLog(final boolean includeMerged, final SVNRevision truncateTo, final int max) throws VcsException { myClient.doLog(SvnTarget.fromFile(myIoFile), myEndRevision, truncateTo == null ? SVNRevision.create(1L) : truncateTo, false, false, includeMerged, max, null, - new ISVNLogEntryHandler() { - public void handleLogEntry(SVNLogEntry logEntry) { + new LogEntryConsumer() { + @Override + public void consume(LogEntry logEntry) { if (SVNRevision.UNDEFINED.getNumber() == logEntry.getRevision()) { return; } @@ -477,7 +452,8 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn return true; } - private static SVNDiffOptions getLogClientOptions(@NotNull SvnVcs vcs) { - return SvnConfiguration.getInstance(vcs.getProject()).isIgnoreSpacesInAnnotate() ? new SVNDiffOptions(true, true, true) : null; + @Nullable + private static DiffOptions getLogClientOptions(@NotNull SvnVcs vcs) { + return SvnConfiguration.getInstance(vcs.getProject()).isIgnoreSpacesInAnnotate() ? new DiffOptions(true, true, true) : null; } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java index 191bd9079237..c2423de0b70d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java @@ -4,13 +4,17 @@ import com.intellij.openapi.vcs.VcsException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.api.BaseSvnClient; +import org.jetbrains.idea.svn.checkin.CommitInfo; +import org.jetbrains.idea.svn.diff.DiffOptions; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler; -import org.tmatesoft.svn.core.wc.SVNDiffOptions; import org.tmatesoft.svn.core.wc.SVNLogClient; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; +import java.io.File; +import java.util.Date; + /** * @author Konstantin Kolosovsky. */ @@ -22,21 +26,68 @@ public class SvnKitAnnotateClient extends BaseSvnClient implements AnnotateClien @NotNull SVNRevision endRevision, @Nullable SVNRevision pegRevision, boolean includeMergedRevisions, - @Nullable SVNDiffOptions diffOptions, - @Nullable ISVNAnnotateHandler handler) throws VcsException { + @Nullable DiffOptions diffOptions, + @Nullable AnnotationConsumer handler) throws VcsException { try { SVNLogClient client = myVcs.getSvnKitManager().createLogClient(); - client.setDiffOptions(diffOptions); + client.setDiffOptions(toDiffOptions(diffOptions)); if (target.isFile()) { - client.doAnnotate(target.getFile(), pegRevision, startRevision, endRevision, true, includeMergedRevisions, handler, null); + client + .doAnnotate(target.getFile(), pegRevision, startRevision, endRevision, true, includeMergedRevisions, toAnnotateHandler(handler), + null); } else { - client.doAnnotate(target.getURL(), pegRevision, startRevision, endRevision, true, includeMergedRevisions, handler, null); + client + .doAnnotate(target.getURL(), pegRevision, startRevision, endRevision, true, includeMergedRevisions, toAnnotateHandler(handler), + null); } } catch (SVNException e) { throw new VcsException(e); } } + + @Nullable + private static ISVNAnnotateHandler toAnnotateHandler(@Nullable final AnnotationConsumer handler) { + ISVNAnnotateHandler result = null; + + if (handler != null) { + result = new ISVNAnnotateHandler() { + @Override + public void handleLine(Date date, long revision, String author, String line) throws SVNException { + // deprecated - not called + } + + @Override + public void handleLine(Date date, + long revision, + String author, + String line, + Date mergedDate, + long mergedRevision, + String mergedAuthor, + String mergedPath, + int lineNumber) throws SVNException { + if (revision > 0) { + CommitInfo info = new CommitInfo.Builder(revision, date, author).build(); + CommitInfo mergeInfo = mergedDate != null ? new CommitInfo.Builder(mergedRevision, mergedDate, mergedAuthor).build() : null; + + handler.consume(lineNumber, info, mergeInfo); + } + } + + @Override + public boolean handleRevision(Date date, long revision, String author, File contents) throws SVNException { + return false; + } + + @Override + public void handleEOF() throws SVNException { + } + }; + } + + return result; + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnRemoteFileAnnotation.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnRemoteFileAnnotation.java index f00bc7b97aaa..3f0924650c5f 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnRemoteFileAnnotation.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnRemoteFileAnnotation.java @@ -29,15 +29,10 @@ import org.jetbrains.idea.svn.history.SvnChangeList; * Time: 12:10 PM */ public class SvnRemoteFileAnnotation extends BaseSvnFileAnnotation { - private final SvnChangeList mySvnChangeList; - private final String myPathToSelect; private final VirtualFile myCurrentFile; - public SvnRemoteFileAnnotation(SvnVcs vcs, String contents, VcsRevisionNumber baseRevision, SvnChangeList svnChangeList, - final String pathToSelect, final VirtualFile currentFile) { + public SvnRemoteFileAnnotation(SvnVcs vcs, String contents, VcsRevisionNumber baseRevision, final VirtualFile currentFile) { super(vcs, contents, baseRevision); - mySvnChangeList = svnChangeList; - myPathToSelect = pathToSelect; myCurrentFile = currentFile; } |