| /* |
| * 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.history; |
| |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.progress.ProgressIndicator; |
| import com.intellij.openapi.progress.ProgressManager; |
| import com.intellij.openapi.util.Throwable2Computable; |
| import com.intellij.openapi.vcs.RepositoryLocation; |
| import com.intellij.openapi.vcs.VcsException; |
| import com.intellij.openapi.vcs.history.VcsFileRevision; |
| import com.intellij.openapi.vcs.history.VcsRevisionNumber; |
| import com.intellij.openapi.vcs.impl.ContentRevisionCache; |
| import com.intellij.vcsUtil.VcsUtil; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.jetbrains.idea.svn.SvnBundle; |
| import org.jetbrains.idea.svn.SvnRevisionNumber; |
| import org.jetbrains.idea.svn.SvnUtil; |
| import org.jetbrains.idea.svn.SvnVcs; |
| import org.jetbrains.idea.svn.checkin.CommitInfo; |
| import org.tmatesoft.svn.core.wc.SVNRevision; |
| import org.tmatesoft.svn.core.wc2.SvnTarget; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.List; |
| |
| public class SvnFileRevision implements VcsFileRevision { |
| private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.SvnFileRevision"); |
| |
| private final Date myDate; |
| private String myCommitMessage; |
| private final String myAuthor; |
| private final SvnRevisionNumber myRevisionNumber; |
| private final SvnVcs myVCS; |
| private final String myURL; |
| private final SVNRevision myPegRevision; |
| private final SVNRevision myRevision; |
| private final String myCopyFromPath; |
| private final List<SvnFileRevision> myMergeSources; |
| |
| public SvnFileRevision(SvnVcs vcs, |
| SVNRevision pegRevision, |
| SVNRevision revision, |
| String url, |
| String author, |
| Date date, |
| String commitMessage, |
| String copyFromPath) { |
| myRevisionNumber = new SvnRevisionNumber(revision); |
| myPegRevision = pegRevision; |
| myRevision = revision; |
| myAuthor = author; |
| myDate = date; |
| myCommitMessage = commitMessage; |
| myCopyFromPath = copyFromPath; |
| myVCS = vcs; |
| myURL = url; |
| myMergeSources = new ArrayList<SvnFileRevision>(); |
| } |
| |
| public SvnFileRevision(SvnVcs vcs, |
| SVNRevision pegRevision, |
| LogEntry logEntry, |
| String url, |
| String copyFromPath) { |
| final SVNRevision revision = SVNRevision.create(logEntry.getRevision()); |
| myRevisionNumber = new SvnRevisionNumber(revision); |
| myPegRevision = pegRevision; |
| myRevision = revision; |
| myAuthor = logEntry.getAuthor(); |
| myDate = logEntry.getDate(); |
| myCommitMessage = logEntry.getMessage(); |
| myCopyFromPath = copyFromPath; |
| myVCS = vcs; |
| myURL = url; |
| myMergeSources = new ArrayList<SvnFileRevision>(); |
| } |
| |
| @NotNull |
| public CommitInfo getCommitInfo() { |
| return new CommitInfo.Builder(myRevisionNumber.getRevision().getNumber(), myDate, myAuthor).build(); |
| } |
| |
| public String getURL() { |
| return myURL; |
| } |
| |
| public SVNRevision getPegRevision() { |
| return myPegRevision; |
| } |
| |
| |
| public VcsRevisionNumber getRevisionNumber() { |
| return myRevisionNumber; |
| } |
| |
| public String getBranchName() { |
| return null; |
| } |
| |
| @Nullable |
| @Override |
| public RepositoryLocation getChangedRepositoryPath() { |
| return new SvnRepositoryLocation(myURL); |
| } |
| |
| public Date getRevisionDate() { |
| return myDate; |
| } |
| |
| public String getAuthor() { |
| return myAuthor; |
| } |
| |
| public String getCommitMessage() { |
| return myCommitMessage; |
| } |
| |
| public void addMergeSource(final SvnFileRevision source) { |
| myMergeSources.add(source); |
| } |
| |
| public List<SvnFileRevision> getMergeSources() { |
| return myMergeSources; |
| } |
| |
| public byte[] loadContent() throws IOException, VcsException { |
| ContentLoader loader = new ContentLoader(myURL, myRevision, myPegRevision); |
| if (ApplicationManager.getApplication().isDispatchThread() && |
| !myRevision.isLocal()) { |
| ProgressManager.getInstance().runProcessWithProgressSynchronously(loader, SvnBundle.message("progress.title.loading.file.content"), |
| false, myVCS.getProject()); |
| } |
| else { |
| loader.run(); |
| } |
| |
| VcsException exception = loader.getException(); |
| if (exception == null) { |
| final byte[] contents = loader.getContents(); |
| ContentRevisionCache.checkContentsSize(myURL, contents.length); |
| return contents; |
| } |
| else { |
| LOG.info("Failed to load file '" + myURL + "' content at revision: " + myRevision + "\n" + exception.getMessage(), exception); |
| throw exception; |
| } |
| } |
| |
| public byte[] getContent() throws IOException, VcsException { |
| byte[] result; |
| |
| if (SVNRevision.HEAD.equals(myRevision)) { |
| result = loadContent(); |
| } |
| else { |
| result = ContentRevisionCache.getOrLoadAsBytes(myVCS.getProject(), VcsUtil.getFilePathOnNonLocal(myURL, false), getRevisionNumber(), |
| myVCS.getKeyInstanceMethod(), ContentRevisionCache.UniqueType.REMOTE_CONTENT, |
| new Throwable2Computable<byte[], VcsException, IOException>() { |
| @Override |
| public byte[] compute() throws VcsException, IOException { |
| return loadContent(); |
| } |
| }); |
| } |
| |
| return result; |
| } |
| |
| public String getCopyFromPath() { |
| return myCopyFromPath; |
| } |
| |
| public void setCommitMessage(String message) { |
| myCommitMessage = message; |
| } |
| |
| private class ContentLoader implements Runnable { |
| private final SVNRevision myRevision; |
| private final SVNRevision myPegRevision; |
| private final String myURL; |
| private VcsException myException; |
| private byte[] myContents; |
| |
| public ContentLoader(String url, SVNRevision revision, SVNRevision pegRevision) { |
| myURL = url; |
| myRevision = revision; |
| myPegRevision = pegRevision; |
| } |
| |
| public VcsException getException() { |
| return myException; |
| } |
| |
| private byte[] getContents() { |
| return myContents; |
| } |
| |
| public void run() { |
| ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); |
| if (progress != null) { |
| progress.setText(SvnBundle.message("progress.text.loading.contents", myURL)); |
| progress.setText2(SvnBundle.message("progress.text2.revision.information", myRevision)); |
| } |
| |
| try { |
| myContents = SvnUtil.getFileContents(myVCS, SvnTarget.fromURL(SvnUtil.parseUrl(myURL)), myRevision, myPegRevision); |
| } |
| catch (VcsException e) { |
| myException = e; |
| } |
| } |
| } |
| |
| public SVNRevision getRevision() { |
| return myRevision; |
| } |
| } |