KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ui > history > EditionHistoryPage


1 /*******************************************************************************
2  * Copyright (c) 2006, 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 package org.eclipse.team.internal.ui.history;
12
13 import java.util.*;
14
15 import org.eclipse.compare.ITypedElement;
16 import org.eclipse.compare.internal.CompareUIPlugin;
17 import org.eclipse.compare.internal.StructureCreatorDescriptor;
18 import org.eclipse.compare.structuremergeviewer.*;
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.runtime.*;
22 import org.eclipse.osgi.util.NLS;
23 import org.eclipse.swt.graphics.Image;
24 import org.eclipse.team.core.TeamException;
25 import org.eclipse.team.core.history.IFileRevision;
26 import org.eclipse.team.internal.core.history.LocalFileHistory;
27 import org.eclipse.team.internal.ui.*;
28 import org.eclipse.team.internal.ui.actions.CompareRevisionAction;
29 import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement;
30 import org.eclipse.team.ui.history.IHistoryPage;
31 import org.eclipse.team.ui.history.IHistoryPageSite;
32 import org.eclipse.ui.IWorkbenchPage;
33
34 /**
35  * A history page for a sub-element of a file.
36  * <p>
37  * If the site is modal, the local edition is created up-front and destroyed when the page is destroyed.
38  * Otherwise, the local edition is only created when needed. The {@link #getCompareInput(Object)} and
39  * {@link #prepareInput(ICompareInput, org.eclipse.compare.CompareConfiguration, IProgressMonitor)}
40  * methods are only used when the site is modal so they can use the localEdition.
41  */

42 public class EditionHistoryPage extends LocalHistoryPage {
43     
44     private final IFile file;
45     private final Object JavaDoc element;
46     private final LocalResourceTypedElement localFileElement;
47     private IStructureCreator structureCreator;
48     private Map editions = new HashMap();
49     private ITypedElement localEdition;
50     private String JavaDoc name;
51     
52     class CompareEditionAction extends CompareRevisionAction {
53         
54         protected ITypedElement getElementFor(IResource resource) {
55             if (resource.equals(file))
56                 return localFileElement;
57             return super.getElementFor(resource);
58         }
59         
60         protected CompareFileRevisionEditorInput createCompareEditorInput(ITypedElement left, ITypedElement right, IWorkbenchPage page) {
61             ITypedElement leftEdition = getEdition(left);
62             boolean leftIsLocal = false;
63             if (leftEdition == null && left instanceof LocalResourceTypedElement) {
64                 leftEdition = createLocalEdition(structureCreator, localFileElement, element);
65                 leftIsLocal = true;
66             }
67             ITypedElement rightEdition = getEdition(right);
68             return new CompareEditionsEditorInput(structureCreator, left, right, leftEdition, rightEdition, leftIsLocal, page);
69         }
70
71         private ITypedElement getEdition(ITypedElement input) {
72             if (input instanceof FileRevisionTypedElement) {
73                 FileRevisionTypedElement te = (FileRevisionTypedElement) input;
74                 return getEditionFor(te.getRevision());
75             }
76             return null;
77         }
78     }
79     
80     static class CompareEditionsEditorInput extends CompareFileRevisionEditorInput {
81
82         private final ITypedElement leftRevision;
83         private final ITypedElement rightRevision;
84         private final boolean leftIsLocal;
85         private IStructureCreator structureCreator;
86
87         public CompareEditionsEditorInput(IStructureCreator structureCreator, ITypedElement left,
88                 ITypedElement right, ITypedElement leftEdition,
89                 ITypedElement rightEdition, boolean leftIsLocal, IWorkbenchPage page) {
90             super(leftEdition, rightEdition, page);
91             this.structureCreator = structureCreator;
92             leftRevision = left;
93             rightRevision = right;
94             this.leftIsLocal = leftIsLocal;
95         }
96         
97         public LocalResourceTypedElement getLocalElement() {
98             if (leftRevision instanceof LocalResourceTypedElement) {
99                 return (LocalResourceTypedElement) leftRevision;
100             }
101             return super.getLocalElement();
102         }
103         
104         protected FileRevisionTypedElement getRightRevision() {
105             if (rightRevision instanceof FileRevisionTypedElement) {
106                 return (FileRevisionTypedElement) rightRevision;
107             }
108             return null;
109         }
110
111         protected FileRevisionTypedElement getLeftRevision() {
112             if (leftRevision instanceof FileRevisionTypedElement) {
113                 return (FileRevisionTypedElement) leftRevision;
114             }
115             return null;
116         }
117         public Object JavaDoc getAdapter(Class JavaDoc adapter) {
118             if (adapter == IFile.class)
119                 return null;
120             return super.getAdapter(adapter);
121         }
122         
123         protected void handleDispose() {
124             if (leftIsLocal && structureCreator != null)
125                 internalDestroy(structureCreator, getLeft());
126             structureCreator = null;
127             super.handleDispose();
128         }
129     }
130     
131     public static ITypedElement getPreviousState(IFile file, Object JavaDoc element) throws TeamException {
132         LocalResourceTypedElement localFileElement= new LocalResourceTypedElement(file);
133         IStructureCreator structureCreator = getStructureCreator(localFileElement);
134         if (structureCreator == null)
135             return null;
136         LocalFileHistory history = new LocalFileHistory(file, false);
137         history.refresh(new NullProgressMonitor());
138         IFileRevision[] revisions = history.getFileRevisions();
139         if (revisions.length == 0)
140             return null;
141         sortDescending(revisions);
142         ITypedElement localEdition = null;
143         try {
144             localEdition = createLocalEdition(structureCreator, localFileElement, element);
145             for (int i = 0; i < revisions.length; i++) {
146                 IFileRevision revision = revisions[i];
147                 ITypedElement edition = createEdition(structureCreator, element, new FileRevisionTypedElement(revision));
148                 if (edition != null && !contentsEqual(structureCreator, localEdition, edition)) {
149                     return edition;
150                 }
151             }
152         } finally {
153             if (localEdition != null)
154                 destroyLocalEdition(structureCreator, localFileElement, localEdition);
155         }
156         return null;
157     }
158
159     private static IStructureCreator getStructureCreator(ITypedElement element) {
160         StructureCreatorDescriptor scd= CompareUIPlugin.getDefault().getStructureCreator(element.getType());
161         if (scd != null) {
162             return scd.createStructureCreator();
163         }
164         return null;
165     }
166     
167     public EditionHistoryPage(IFile file, Object JavaDoc element) {
168         super(ON | ALWAYS);
169         Assert.isNotNull(file);
170         Assert.isNotNull(element);
171         this.file = file;
172         this.element = element;
173         this.localFileElement= new LocalResourceTypedElement(getFile());
174         structureCreator = getStructureCreator(localFileElement);
175     }
176
177     public void setSite(IHistoryPageSite site) {
178         super.setSite(site);
179         // If the site is modal, create the local edition
180
if (site.isModal()) {
181             localEdition = createLocalEdition(structureCreator, localFileElement, element);
182         }
183     }
184     
185     /* (non-Javadoc)
186      * @see org.eclipse.team.internal.ui.history.LocalHistoryPage#getFile()
187      */

188     protected IFile getFile() {
189         return file;
190     }
191
192     /* (non-Javadoc)
193      * @see org.eclipse.team.internal.ui.history.LocalHistoryPage#update(org.eclipse.team.core.history.IFileRevision[], org.eclipse.core.runtime.IProgressMonitor)
194      */

195     protected void update(IFileRevision[] revisions, IProgressMonitor monitor) {
196         monitor.beginTask(null, 100);
197         ITypedElement te = null;
198         try {
199             if (localEdition == null) {
200                 te = createLocalEdition(structureCreator, localFileElement, element);
201             } else {
202                 te = localEdition;
203             }
204             if (te != null) {
205                 String JavaDoc oldValue = getName();
206                 String JavaDoc oldDesc = getDescription();
207                 name = te.getName();
208                 IFileRevision[] filtered = filterRevisions(te, revisions, Policy.subMonitorFor(monitor, 75));
209                 super.update(filtered, Policy.subMonitorFor(monitor, 25));
210                 firePropertyChange(this, IHistoryPage.P_NAME, oldValue, getName());
211                 firePropertyChange(this, IHistoryPage.P_DESCRIPTION, oldDesc, getDescription());
212             }
213         } finally {
214             if (localEdition == null && te != null)
215                 internalDestroy(structureCreator, te);
216             monitor.done();
217         }
218     }
219
220     private IFileRevision[] filterRevisions(ITypedElement localEdition, IFileRevision[] revisions,
221             IProgressMonitor monitor) {
222         ITypedElement previousEdition = localEdition;
223         List result = new ArrayList();
224         sortDescending(revisions);
225         editions.clear();
226         for (int i = 0; i < revisions.length; i++) {
227             IFileRevision revision = revisions[i];
228             ITypedElement edition = createEdition(new FileRevisionTypedElement(revision));
229             if (edition != null && !contentsEqual(structureCreator, previousEdition, edition)) {
230                 editions.put(revision, edition);
231                 previousEdition = edition;
232                 result.add(revision);
233             }
234         }
235         return (IFileRevision[]) result.toArray(new IFileRevision[result.size()]);
236     }
237     
238     private static void sortDescending(IFileRevision[] revisions) {
239         Arrays.sort(revisions, new Comparator() {
240             public int compare(Object JavaDoc o1, Object JavaDoc o2) {
241                 IFileRevision d1= (IFileRevision) o1;
242                 IFileRevision d2= (IFileRevision) o2;
243                 long d= d2.getTimestamp() - d1.getTimestamp();
244                 if (d < 0)
245                     return -1;
246                 if (d > 0)
247                     return 1;
248                 return 0;
249             }
250         });
251     }
252
253     private static boolean contentsEqual(IStructureCreator creator, ITypedElement previousEdition,
254             ITypedElement edition) {
255         if (previousEdition == null || creator == null || edition == null)
256             return false;
257         String JavaDoc contents1 = creator.getContents(previousEdition, false /* TODO: Ignore whitespace */);
258         String JavaDoc contents2 = creator.getContents(edition, false /* TODO: Ignore whitespace */);
259         return (contents1 != null && contents2 != null && contents1.equals(contents2));
260     }
261
262     /* (non-Javadoc)
263      * @see org.eclipse.team.internal.ui.history.LocalHistoryPage#getCompareInput(java.lang.Object)
264      */

265     public ICompareInput getCompareInput(Object JavaDoc object) {
266         ITypedElement edition = getEditionFor(object);
267         if (edition != null && localEdition != null)
268             return new DiffNode(localEdition, edition);
269         return null;
270     }
271
272     public ITypedElement getEditionFor(Object JavaDoc object) {
273         return (ITypedElement)editions.get(object);
274     }
275     
276     private static ITypedElement createLocalEdition(IStructureCreator creator, ITypedElement input, Object JavaDoc element) {
277         if (creator == null)
278             return null;
279         ITypedElement result = null;
280         if (creator instanceof IStructureCreator2) {
281             IStructureCreator2 sc2 = (IStructureCreator2) creator;
282             try {
283                 result = sc2.createElement(element, input, null);
284             } catch (CoreException e) {
285                 TeamUIPlugin.log(e);
286             }
287         }
288         if (result == null) {
289             result = createEdition(creator, element, input);
290         }
291         return result;
292     }
293     
294     private ITypedElement createEdition(ITypedElement input) {
295         return createEdition(structureCreator, element, input);
296     }
297     
298     private static ITypedElement createEdition(IStructureCreator creator, Object JavaDoc element, ITypedElement input) {
299         if (creator == null)
300             return null;
301         IStructureComparator edition = creator.locate(element, input);
302         if (edition instanceof ITypedElement)
303             return (ITypedElement) edition;
304         return null;
305     }
306     
307     /* (non-Javadoc)
308      * @see org.eclipse.team.internal.ui.history.LocalHistoryPage#isValidInput(java.lang.Object)
309      */

310     public boolean isValidInput(Object JavaDoc object) {
311         // This page doesn't support input changes
312
return object.equals(element);
313     }
314     
315     /* (non-Javadoc)
316      * @see org.eclipse.team.internal.ui.history.LocalHistoryPage#dispose()
317      */

318     public void dispose() {
319         try {
320             disconnect();
321         } finally {
322             super.dispose();
323         }
324     }
325     
326     private void disconnect() {
327         if (localFileElement != null)
328             localFileElement.discardBuffer();
329         internalDestroy(structureCreator, localEdition);
330         localEdition = null;
331         structureCreator = null;
332     }
333
334     private static void internalDestroy(IStructureCreator creator, ITypedElement te) {
335         if (te != null && creator instanceof IStructureCreator2) {
336             IStructureCreator2 sc2 = (IStructureCreator2) creator;
337             sc2.destroy(te);
338         }
339     }
340     
341     private static void destroyLocalEdition(
342             IStructureCreator structureCreator, LocalResourceTypedElement localFileElement, ITypedElement localEdition) {
343         if (localFileElement != null)
344             localFileElement.discardBuffer();
345         if (localEdition != null && structureCreator instanceof IStructureCreator2) {
346             IStructureCreator2 sc2 = (IStructureCreator2) structureCreator;
347             sc2.destroy(localEdition);
348         }
349     }
350     
351     /* (non-Javadoc)
352      * @see org.eclipse.team.internal.ui.history.LocalHistoryPage#getNoChangesMessage()
353      */

354     protected String JavaDoc getNoChangesMessage() {
355         if (name != null)
356             return NLS.bind(TeamUIMessages.EditionHistoryPage_0, name);
357         return TeamUIMessages.EditionHistoryPage_1;
358     }
359     
360     protected Image getImage(Object JavaDoc object) {
361         if (object == localEdition)
362             return localEdition.getImage();
363         Object JavaDoc revision = getRevisionFor(object);
364         if (revision != null)
365             return super.getImage(revision);
366         return super.getImage(object);
367     }
368     
369     protected String JavaDoc getLabel(Object JavaDoc object) {
370         Object JavaDoc revision = getRevisionFor(object);
371         if (revision != null)
372             return super.getLabel(revision);
373         return super.getLabel(object);
374     }
375
376     private Object JavaDoc getRevisionFor(Object JavaDoc object) {
377         if (object == localEdition)
378             return localFileElement;
379         for (Iterator iterator = editions.keySet().iterator(); iterator.hasNext();) {
380             IFileRevision revision = (IFileRevision) iterator.next();
381             if (editions.get(revision) == object) {
382                 return revision;
383             }
384         }
385         return null;
386     }
387     
388     /* (non-Javadoc)
389      * @see org.eclipse.team.internal.ui.history.LocalHistoryPage#getName()
390      */

391     public String JavaDoc getName() {
392         if (name != null)
393             return name;
394         return super.getName();
395     }
396     
397     /* (non-Javadoc)
398      * @see org.eclipse.team.internal.ui.history.LocalHistoryPage#getDescription()
399      */

400     public String JavaDoc getDescription() {
401         if (name != null)
402             return NLS.bind(TeamUIMessages.EditionHistoryPage_2, name);
403         return super.getDescription();
404     }
405     
406     /* (non-Javadoc)
407      * @see org.eclipse.team.internal.ui.history.LocalHistoryPage#createCompareAction()
408      */

409     protected CompareRevisionAction createCompareAction() {
410         return new CompareEditionAction();
411     }
412
413 }
414
Popular Tags