KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > core > filehistory > CVSFileHistory


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.team.internal.ccvs.core.filehistory;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Iterator JavaDoc;
16
17 import org.eclipse.core.resources.*;
18 import org.eclipse.core.runtime.*;
19 import org.eclipse.osgi.util.NLS;
20 import org.eclipse.team.core.RepositoryProvider;
21 import org.eclipse.team.core.TeamException;
22 import org.eclipse.team.core.history.IFileHistoryProvider;
23 import org.eclipse.team.core.history.IFileRevision;
24 import org.eclipse.team.core.history.provider.FileHistory;
25 import org.eclipse.team.internal.ccvs.core.*;
26 import org.eclipse.team.internal.ccvs.core.client.Session;
27 import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
28 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
29 import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
30
31 public class CVSFileHistory extends FileHistory {
32
33     public static final int REFRESH_LOCAL = 1;
34     public static final int REFRESH_REMOTE = 2;
35     
36     public static final int REFRESH_ALL = REFRESH_LOCAL | REFRESH_REMOTE;
37     
38     private final ICVSFile cvsFile;
39     //used to hold all revisions (changes based on filtering)
40
protected IFileRevision[] revisions;
41     //used to hold all of the remote revisions
42
protected IFileRevision[] remoteRevisions;
43     //used to hold all of the local revisions
44
protected IFileRevision[] localRevisions;
45     protected boolean includeLocalRevisions;
46     protected boolean includeRemoteRevisions;
47     protected boolean includesExists;
48     protected boolean refetchRevisions;
49
50     private int flag;
51
52     /*
53      * Creates a new CVSFile history that will fetch remote revisions by default.
54      */

55     public CVSFileHistory(ICVSFile file) {
56         Assert.isNotNull(file);
57         this.cvsFile = file;
58         this.includeLocalRevisions = false;
59         this.includeRemoteRevisions = true;
60         this.refetchRevisions = true;
61         this.flag = 0;
62     }
63
64     /*
65      *
66      * Creates a new CVSFile history that will fetch remote revisions by default.
67      * The flag passed can be IFileHistoryProvider.SINGLE_REVISION or IFileHistoryProvider.SINGLE_LINE_OF_DESCENT
68      */

69     public CVSFileHistory(ICVSFile file, int flag) {
70         Assert.isNotNull(file);
71         this.cvsFile = file;
72         this.includeLocalRevisions = false;
73         this.includeRemoteRevisions = true;
74         this.refetchRevisions = true;
75         this.flag = flag;
76     }
77
78     public IFileRevision[] getFileRevisions() {
79         if (revisions == null)
80             return new IFileRevision[0];
81         return revisions;
82     }
83
84     /**
85      * Refreshes the revisions for this CVS file. It may or may not contact the server to get new revisions.
86      *
87      * @param monitor a progress monitor
88      */

89     public void refresh(int flags, IProgressMonitor monitor) throws TeamException {
90         if (flags == CVSFileHistory.REFRESH_LOCAL) {
91             fetchLocalOnly(monitor);
92             return;
93         }
94             
95         if (refetchRevisions) {
96             monitor.beginTask(NLS.bind(CVSMessages.CVSFileHistory_0, cvsFile.getRepositoryRelativePath()), 300);
97             try {
98                 ILogEntry[] entries = cvsFile.getLogEntries(new SubProgressMonitor(monitor, 200));
99                 
100                 if (entries.length == 0){
101                     //Get the parent folder
102
ICVSFolder folder = cvsFile.getParent();
103                     if (folder.isManaged()){
104                         String JavaDoc remoteFolderLocation = folder.getRemoteLocation(folder);
105                         String JavaDoc remoteFileName = remoteFolderLocation.concat(Session.SERVER_SEPARATOR + cvsFile.getName());
106                         //Create remote file
107
CVSTeamProvider pro = (CVSTeamProvider) RepositoryProvider.getProvider(cvsFile.getIResource().getProject());
108                         if (pro != null){
109                             CVSWorkspaceRoot root = pro.getCVSWorkspaceRoot();
110                             CVSRepositoryLocation location = CVSRepositoryLocation.fromString(root.getRemoteLocation().getLocation(false));
111                             RemoteFile remFile = RemoteFile.create(remoteFileName, location);
112                             entries=remFile.getLogEntries(monitor);
113                         }
114                     }
115                 }
116                 
117                 if (flag == IFileHistoryProvider.SINGLE_REVISION) {
118                     String JavaDoc revisionNumber = cvsFile.getSyncInfo().getRevision();
119                     for (int i = 0; i < entries.length; i++) {
120                         if (entries[i].getRevision().equals(revisionNumber)) {
121                             remoteRevisions = new IFileRevision[] {new CVSFileRevision(entries[i])};
122                             revisions = new IFileRevision[1];
123                             //copy over remote revisions
124
System.arraycopy(remoteRevisions, 0, revisions, 0, remoteRevisions.length);
125                             break;
126                         }
127                     }
128
129                 } else if (flag == IFileHistoryProvider.SINGLE_LINE_OF_DESCENT) {
130                     CVSTag tempTag = cvsFile.getSyncInfo().getTag();
131                     ArrayList JavaDoc entriesOfInterest = new ArrayList JavaDoc();
132                     for (int i = 0; i < entries.length; i++) {
133                         CVSTag[] tags = entries[i].getTags();
134                         for (int j = 0; j < tags.length; j++) {
135                             if (tags[j].getType() == tempTag.getType()) {
136                                 if (tempTag.getType() == CVSTag.BRANCH && tempTag.getName().equals(tags[j].getName())) {
137                                     entriesOfInterest.add(entries[i]);
138                                     break;
139                                 } else {
140                                     entriesOfInterest.add(entries[i]);
141                                     break;
142                                 }
143                             }
144
145                         }
146                     }
147
148                     //always fetch the remote revisions, just filter them out from the returned array
149
remoteRevisions = new IFileRevision[entriesOfInterest.size()];
150                     Iterator JavaDoc iter = entriesOfInterest.iterator();
151                     int i = 0;
152                     while (iter.hasNext()) {
153                         remoteRevisions[i++] = new CVSFileRevision((ILogEntry) iter.next());
154                     }
155
156                     //copy over remote revisions
157
revisions = new IFileRevision[remoteRevisions.length];
158                     System.arraycopy(remoteRevisions, 0, revisions, 0, remoteRevisions.length);
159
160                 } else {
161                     localRevisions = new IFileRevision[0];
162                     //always fetch the local revisions, just filter them out from the returned array if not wanted
163
IResource localResource = cvsFile.getIResource();
164                     includesExists = false;
165                     if (localResource != null && localResource instanceof IFile) {
166                         //get the local revisions
167
IFileState[] localHistoryState;
168                         try {
169                             localHistoryState = ((IFile) localResource).getHistory(new SubProgressMonitor(monitor, 100));
170                             localRevisions = convertToFileRevision(localHistoryState, new SubProgressMonitor(monitor, 100));
171                             includesExists = (localRevisions.length > 0);
172                         } catch (CoreException e) {
173                             TeamException.asTeamException(e);
174                         }
175                     }
176
177                     //always fetch the remote revisions, just filter them out from the returned array
178
remoteRevisions = new IFileRevision[entries.length];
179                     for (int i = 0; i < entries.length; i++) {
180                         remoteRevisions[i] = new CVSFileRevision(entries[i]);
181                     }
182
183                     revisions = new IFileRevision[0];
184                     arrangeRevisions();
185                 }
186             } finally {
187                 monitor.done();
188             }
189         } else {
190             //don't refetch revisions just return revisions with local revisions as requested
191
arrangeRevisions();
192         }
193         
194     }
195
196     private void arrangeRevisions() {
197         if (revisions != null) {
198             if (includeLocalRevisions && includeRemoteRevisions) {
199                 //Local + Remote mode
200
revisions = new IFileRevision[remoteRevisions.length + localRevisions.length];
201                 //copy over remote revisions
202
System.arraycopy(remoteRevisions, 0, revisions, 0, remoteRevisions.length);
203                 //copy over local revisions
204
System.arraycopy(localRevisions, 0, revisions, remoteRevisions.length, localRevisions.length);
205             } else if (includeLocalRevisions) {
206                 //Local mode only
207
revisions = new IFileRevision[localRevisions.length];
208                 //copy over local revisions
209
System.arraycopy(localRevisions, 0, revisions, 0, localRevisions.length);
210             } else if (includeRemoteRevisions) {
211                 //Remote mode and fall through for Local + Remote mode where no Locals exist
212
revisions = new IFileRevision[remoteRevisions.length];
213                 //copy over remote revisions
214
System.arraycopy(remoteRevisions, 0, revisions, 0, remoteRevisions.length);
215             }
216         }
217     }
218
219     public IFileRevision getFileRevision(String JavaDoc id) {
220         IFileRevision[] revisions = getFileRevisions();
221         for (int i = 0; i < revisions.length; i++) {
222             if (revisions[i].getContentIdentifier().equals(id))
223                 return revisions[i];
224         }
225         return null;
226     }
227
228     public IFileRevision[] getContributors(IFileRevision revision) {
229
230         IFileRevision[] revisions = getFileRevisions();
231
232         //the predecessor is the file with a timestamp that is the largest timestamp
233
//from the set of all timestamps smaller than the root file's timestamp
234
IFileRevision fileRevision = null;
235         for (int i = 0; i < revisions.length; i++) {
236             if (((CVSFileRevision) revisions[i]).isPredecessorOf(revision)) {
237                 //no revision has been set as of yet
238
if (fileRevision == null)
239                     fileRevision = revisions[i];
240                 //this revision is a predecessor - now check to see if it comes
241
//after the current predecessor, if it does make it the current predecessor
242
if (revisions[i].getTimestamp() > fileRevision.getTimestamp()) {
243                     fileRevision = revisions[i];
244                 }
245             }
246         }
247         if (fileRevision == null)
248             return new IFileRevision[0];
249         return new IFileRevision[] {fileRevision};
250     }
251
252     public IFileRevision[] getTargets(IFileRevision revision) {
253         IFileRevision[] revisions = getFileRevisions();
254
255         //the predecessor is the file with a timestamp that is the largest timestamp
256
//from the set of all timestamps smaller than the root file's timestamp
257
ArrayList JavaDoc directDescendents = new ArrayList JavaDoc();
258
259         for (int i = 0; i < revisions.length; i++) {
260             if (((CVSFileRevision) revisions[i]).isDescendentOf(revision)) {
261                 directDescendents.add(revisions[i]);
262             }
263         }
264         return (IFileRevision[]) directDescendents.toArray(new IFileRevision[directDescendents.size()]);
265     }
266
267     private IFileRevision[] convertToFileRevision(IFileState[] localRevisions, IProgressMonitor monitor) {
268         boolean modified = false;
269         try {
270             modified = cvsFile.isModified(monitor);
271         } catch (CVSException e) {
272         }
273
274         IFile localFile = (IFile) cvsFile.getIResource();
275         boolean localFileExists = (localFile != null && localFile.exists());
276         int arrayLength = 0;
277         if (modified && localFileExists)
278             arrayLength++;
279
280         arrayLength += localRevisions.length;
281
282         IFileRevision[] fileRevisions = new IFileRevision[arrayLength];
283         for (int i = 0; i < localRevisions.length; i++) {
284             IFileState localFileState = localRevisions[i];
285             CVSLocalFileRevision localRevision = new CVSLocalFileRevision(localFileState);
286             fileRevisions[i] = localRevision;
287         }
288
289         if (modified && localFileExists) {
290             CVSLocalFileRevision currentFile = new CVSLocalFileRevision(localFile);
291             CVSFileHistoryProvider provider = new CVSFileHistoryProvider();
292             currentFile.setBaseRevision(provider.getWorkspaceFileRevision(localFile));
293             fileRevisions[localRevisions.length] = currentFile;
294         }
295
296         return fileRevisions;
297     }
298
299     public void includeLocalRevisions(boolean flag) {
300         this.includeLocalRevisions = flag;
301     }
302
303     public boolean getIncludesExists() {
304         return includesExists;
305     }
306
307     public void setRefetchRevisions(boolean refetch) {
308         this.refetchRevisions = refetch;
309     }
310
311     public void includeRemoteRevisions(boolean flag) {
312         this.includeRemoteRevisions = flag;
313     }
314
315     public void fetchLocalOnly(IProgressMonitor monitor) {
316         try{
317         localRevisions = new IFileRevision[0];
318         //always fetch the local revisions, just filter them out from the returned array if not wanted
319
IResource localResource = cvsFile.getIResource();
320         includesExists = false;
321         if (localResource != null && localResource instanceof IFile) {
322             //get the local revisions
323
IFileState[] localHistoryState = ((IFile) localResource).getHistory(new SubProgressMonitor(monitor, 100));
324             localRevisions = convertToFileRevision(localHistoryState, new SubProgressMonitor(monitor, 100));
325             includesExists = (localRevisions.length > 0);
326         }
327
328         if (remoteRevisions == null)
329             remoteRevisions = new IFileRevision[0];
330         revisions = new IFileRevision[0];
331         arrangeRevisions();
332         } catch (CoreException ex){
333             //nothing to do - calling getFileRevisions() when revisions is null will result in
334
//revisions returning an empty array
335
} finally {
336             monitor.done();
337         }
338     }
339
340     public boolean isInitialized() {
341         return revisions != null;
342     }
343
344     public boolean isIncludeLocal() {
345         return includeLocalRevisions;
346     }
347 }
348
Popular Tags