1 /******************************************************************************* 2 * Copyright (c) 2006, 2017 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.team.internal.core.history; 15 16 import java.util.ArrayList; 17 18 import org.eclipse.core.resources.IFile; 19 import org.eclipse.core.resources.IFileState; 20 import org.eclipse.core.runtime.CoreException; 21 import org.eclipse.core.runtime.IProgressMonitor; 22 import org.eclipse.team.core.TeamException; 23 import org.eclipse.team.core.history.IFileRevision; 24 import org.eclipse.team.core.history.provider.FileHistory; 25 import org.eclipse.team.internal.core.Messages; 26 27 public class LocalFileHistory extends FileHistory { 28 29 protected IFile file; 30 //used to hold all revisions (changes based on filtering) 31 protected IFileRevision[] revisions; 32 private final boolean includeCurrent; 33 34 /* 35 * Creates a new CVSFile history that will fetch remote revisions by default. 36 */ LocalFileHistory(IFile file, boolean includeCurrent)37 public LocalFileHistory(IFile file, boolean includeCurrent) { 38 this.file = file; 39 this.includeCurrent = includeCurrent; 40 } 41 42 @Override getContributors(IFileRevision revision)43 public IFileRevision[] getContributors(IFileRevision revision) { 44 45 IFileRevision[] revisions = getFileRevisions(); 46 47 //the predecessor is the file with a timestamp that is the largest timestamp 48 //from the set of all timestamps smaller than the root file's timestamp 49 IFileRevision fileRevision = null; 50 for (IFileRevision r : revisions) { 51 if (((LocalFileRevision) r).isPredecessorOf(revision)) { 52 //no revision has been set as of yet 53 if (fileRevision == null) { 54 fileRevision = r; 55 } 56 //this revision is a predecessor - now check to see if it comes 57 //after the current predecessor, if it does make it the current predecessor 58 if (fileRevision != null && r.getTimestamp() > fileRevision.getTimestamp()) { 59 fileRevision = r; 60 } 61 } 62 } 63 if (fileRevision == null) 64 return new IFileRevision[0]; 65 return new IFileRevision[] {fileRevision}; 66 } 67 68 @Override getFileRevision(String id)69 public IFileRevision getFileRevision(String id) { 70 if (revisions != null) { 71 for (IFileRevision revision : revisions) { 72 if (revision.getContentIdentifier().equals(id)) { 73 return revision; 74 } 75 } 76 } 77 return null; 78 } 79 80 @Override getFileRevisions()81 public IFileRevision[] getFileRevisions() { 82 if (revisions == null) 83 return new IFileRevision[0]; 84 return revisions; 85 } 86 87 @Override getTargets(IFileRevision revision)88 public IFileRevision[] getTargets(IFileRevision revision) { 89 IFileRevision[] revisions = getFileRevisions(); 90 ArrayList<IFileRevision> directDescendents = new ArrayList<>(); 91 92 for (IFileRevision r : revisions) { 93 if (((LocalFileRevision) r).isDescendentOf(revision)) { 94 directDescendents.add(r); 95 } 96 } 97 return directDescendents.toArray(new IFileRevision[directDescendents.size()]); 98 } 99 100 /** 101 * Refreshes the revisions for this local file. 102 * 103 * @param monitor a progress monitor 104 * @throws TeamException 105 */ refresh(IProgressMonitor monitor)106 public void refresh(IProgressMonitor monitor) throws TeamException { 107 monitor.beginTask(Messages.LocalFileHistory_RefreshLocalHistory/*, file.getProjectRelativePath().toString())*/, 300); 108 try { 109 // Include the file's current state if and only if the file exists. 110 LocalFileRevision currentRevision = 111 (includeRevisionForFile() ? new LocalFileRevision(file) : null); 112 IFileState[] fileStates = file.getHistory(monitor); 113 int numRevisions = fileStates.length + (currentRevision != null ? 1 : 0); 114 revisions = new LocalFileRevision[numRevisions]; 115 for (int i = 0; i < fileStates.length; i++) { 116 revisions[i] = new LocalFileRevision(fileStates[i]); 117 } 118 if (currentRevision != null) 119 revisions[fileStates.length] = currentRevision; 120 } catch (CoreException e) { 121 throw TeamException.asTeamException(e); 122 } finally { 123 monitor.done(); 124 } 125 } 126 includeRevisionForFile()127 private boolean includeRevisionForFile() { 128 return file.exists() && includeCurrent; 129 } 130 131 } 132