KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > ui > wizards > RestoreFromRepositoryFileSelectionPage


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 package org.eclipse.team.internal.ccvs.ui.wizards;
12
13 import java.io.BufferedInputStream JavaDoc;
14 import java.io.InputStream JavaDoc;
15 import java.lang.reflect.InvocationTargetException JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import org.eclipse.compare.*;
21 import org.eclipse.core.resources.*;
22 import org.eclipse.core.runtime.*;
23 import org.eclipse.jface.dialogs.Dialog;
24 import org.eclipse.jface.operation.IRunnableWithProgress;
25 import org.eclipse.jface.resource.ImageDescriptor;
26 import org.eclipse.jface.viewers.*;
27 import org.eclipse.osgi.util.NLS;
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.events.SelectionAdapter;
30 import org.eclipse.swt.events.SelectionEvent;
31 import org.eclipse.swt.graphics.Image;
32 import org.eclipse.swt.layout.GridData;
33 import org.eclipse.swt.widgets.Composite;
34 import org.eclipse.swt.widgets.Widget;
35 import org.eclipse.team.core.TeamException;
36 import org.eclipse.team.core.variants.IResourceVariant;
37 import org.eclipse.team.internal.ccvs.core.*;
38 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
39 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
40 import org.eclipse.team.internal.ccvs.core.util.KnownRepositories;
41 import org.eclipse.team.internal.ccvs.ui.*;
42 import org.eclipse.team.internal.ccvs.ui.Policy;
43 import org.eclipse.ui.PlatformUI;
44 import org.eclipse.ui.model.WorkbenchLabelProvider;
45 import org.eclipse.ui.views.navigator.ResourceSorter;
46
47 /**
48  * Select the files to restore
49  */

50 public class RestoreFromRepositoryFileSelectionPage extends CVSWizardPage {
51     private TreeViewer fileTree;
52     private CompareViewerPane fileSelectionPane;
53     private CompareViewerPane revisionSelectionPane;
54     private CheckboxTableViewer revisionsTable;
55     private CompareViewerSwitchingPane fileContentPane;
56     
57     private HistoryTableProvider historyTableProvider;
58     private AdaptableHierarchicalResourceList treeInput = new AdaptableHierarchicalResourceList(ResourcesPlugin.getWorkspace().getRoot(), new IResource[0]);
59     
60     private IContainer folder;
61     private IFile selectedFile;
62     private ILogEntry selectedRevision;
63     private Map JavaDoc entriesCache = new HashMap JavaDoc();
64     private Map JavaDoc filesToRestore = new HashMap JavaDoc();
65
66     private static final int WIZARD_WIDTH = 550;
67     
68     class HistoryInput implements ITypedElement, IEncodedStreamContentAccessor, IModificationDate {
69         IFile file;
70         ILogEntry logEntry;
71         
72         HistoryInput(IFile file, ILogEntry logEntry) {
73             this.file= file;
74             this.logEntry = logEntry;
75         }
76         public InputStream JavaDoc getContents() throws CoreException {
77             IStorage s = getStorageFromLogEntry(logEntry);
78             if (s == null) return null;
79             return new BufferedInputStream JavaDoc(s.getContents());
80         }
81         public String JavaDoc getName() {
82             return file.getName();
83         }
84         public String JavaDoc getType() {
85             return file.getFileExtension();
86         }
87         public Image getImage() {
88             return CompareUI.getImage(file);
89         }
90         public long getModificationDate() {
91             return logEntry.getDate().getTime();
92         }
93         public String JavaDoc getCharset() throws CoreException {
94             IStorage s = getStorageFromLogEntry(logEntry);
95             if (s instanceof IEncodedStorage) {
96                 return ((IEncodedStorage)s).getCharset();
97             }
98             return null;
99         }
100     }
101     
102     /**
103      * Constructor for RestoreFromRepositoryFileSelectionPage.
104      * @param pageName
105      * @param title
106      * @param titleImage
107      * @param description
108      */

109     public RestoreFromRepositoryFileSelectionPage(
110         String JavaDoc pageName,
111         String JavaDoc title,
112         ImageDescriptor titleImage,
113         String JavaDoc description) {
114         super(pageName, title, titleImage, description);
115     }
116
117     /**
118      * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
119      */

120     public void createControl(Composite parent) {
121         Composite composite= createComposite(parent, 1, false);
122         setControl(composite);
123         
124         PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IHelpContextIds.RESTORE_FROM_REPOSITORY_FILE_SELECTION_PAGE);
125         
126         // Top and bottom panes: top is the two selection panes, bottom is the file content viewer
127
Splitter vsplitter= new Splitter(composite, SWT.VERTICAL);
128         GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL
129                     | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL);
130         // Set the width to be extra wide to accomodate the two selection lists
131
data.widthHint = WIZARD_WIDTH;
132         vsplitter.setLayoutData(data);
133         
134         // Top left and top right panes: the left for the files, the right for the log entries
135
Splitter hsplitter= new Splitter(vsplitter, SWT.HORIZONTAL);
136
137         // Top left: file selection pane
138
fileSelectionPane = new CompareViewerPane(hsplitter, SWT.BORDER | SWT.FLAT);
139         data = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
140         fileSelectionPane.setLayoutData(data);
141         fileTree = createFileSelectionTree(fileSelectionPane);
142         
143         // Top right: Revision selection pane
144
revisionSelectionPane = new CompareViewerPane(hsplitter, SWT.BORDER | SWT.FLAT);
145         data = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
146         revisionSelectionPane.setLayoutData(data);
147         historyTableProvider = new HistoryTableProvider();
148         revisionsTable = createRevisionSelectionTable(revisionSelectionPane, historyTableProvider);
149         revisionSelectionPane.setText(CVSUIMessages.RestoreFromRepositoryFileSelectionPage_emptyRevisionPane);
150         
151         // Bottom: File content viewer
152
fileContentPane = new CompareViewerSwitchingPane(vsplitter, SWT.BORDER | SWT.FLAT) {
153             protected Viewer getViewer(Viewer oldViewer, Object JavaDoc input) {
154                 return CompareUI.findContentViewer(oldViewer, input, this, null);
155             }
156         };
157                         
158         initializeValues();
159         updateWidgetEnablements();
160         Dialog.applyDialogFont(parent);
161     }
162
163     protected CheckboxTableViewer createRevisionSelectionTable(CompareViewerPane composite, HistoryTableProvider tableProvider) {
164         CheckboxTableViewer table = tableProvider.createCheckBoxTable(composite);
165         table.setContentProvider(new IStructuredContentProvider() {
166             public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
167                 ILogEntry[] entries = getSelectedEntries();
168                 if (entries != null) return entries;
169                 return new Object JavaDoc[0];
170             }
171             public void dispose() {
172             }
173             public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {
174             }
175         });
176         table.setInput(this);
177         table.getTable().addSelectionListener(
178             new SelectionAdapter() {
179                 public void widgetSelected(SelectionEvent e) {
180                     // Handle check selection in the check state listener
181
if (e.detail == SWT.CHECK) return;
182                     handleRevisionSelection(e.item);
183                 }
184             }
185         );
186         table.addCheckStateListener(new ICheckStateListener() {
187             public void checkStateChanged(CheckStateChangedEvent event) {
188                 handleRevisionChecked(event);
189             }
190         });
191         composite.setContent(table.getControl());
192         return table;
193     }
194     
195     protected TreeViewer createFileSelectionTree(CompareViewerPane composite) {
196         TreeViewer tree = new TreeViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
197         tree.setUseHashlookup(true);
198         tree.setContentProvider(treeInput.getTreeContentProvider());
199         tree.setLabelProvider(
200             new DecoratingLabelProvider(
201                 new WorkbenchLabelProvider() {
202                     protected String JavaDoc decorateText(String JavaDoc input, Object JavaDoc element) {
203                         String JavaDoc text;
204                         if (element instanceof IFolder && element.equals(folder)) {
205                             text = super.decorateText(folder.getProjectRelativePath().toString(), element);
206                         } else {
207                             ILogEntry entry = (ILogEntry)filesToRestore.get(element);
208                             text = super.decorateText(input, element);
209                             if (entry != null) {
210                                 text = NLS.bind(CVSUIMessages.RestoreFromRepositoryFileSelectionPage_fileToRestore, new String JavaDoc[] { text, entry.getRevision() });
211                             }
212                         }
213                         return text;
214                     }
215                 },
216                 CVSUIPlugin.getPlugin().getWorkbench().getDecoratorManager().getLabelDecorator()));
217         tree.setSorter(new ResourceSorter(ResourceSorter.NAME));
218         tree.setInput(treeInput);
219         
220         GridData data = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL);
221         tree.getTree().setLayoutData(data);
222         tree.addPostSelectionChangedListener(new ISelectionChangedListener() {
223             public void selectionChanged(SelectionChangedEvent event) {
224                 handleFileSelection(event);
225             }
226         });
227         composite.setContent(tree.getControl());
228         return tree;
229     }
230     
231     /**
232      * Method updateWidgetEnablements.
233      */

234     private void updateWidgetEnablements() {
235         
236         if (filesToRestore.isEmpty()) {
237             setPageComplete(false);
238             setErrorMessage(null);
239             return;
240         }
241         
242         for (Iterator JavaDoc iter = filesToRestore.keySet().iterator(); iter.hasNext();) {
243             IFile file = (IFile) iter.next();
244             if (file.exists()) {
245                 setPageComplete(false);
246                 setErrorMessage(NLS.bind(CVSUIMessages.RestoreFromRepositoryFileSelectionPage_fileExists, new String JavaDoc[] { file.getName() }));
247                 return;
248             }
249             
250             ILogEntry entry = (ILogEntry) filesToRestore.get(file);
251             if (entry.isDeletion()) {
252                 setPageComplete(false);
253                 setErrorMessage(NLS.bind(CVSUIMessages.RestoreFromRepositoryFileSelectionPage_revisionIsDeletion, new String JavaDoc[] { entry.getRevision(), file.getName() }));
254                 return;
255             }
256         }
257         setPageComplete(true);
258         setErrorMessage(null);
259     }
260     
261     /**
262      * Method initializeValues.
263      */

264     private void initializeValues() {
265         refresh();
266     }
267
268     /**
269      * Sets the folder.
270      * @param folder The folder to set
271      */

272     public void setInput(IContainer folder, ICVSFile[] files) {
273         if (folder.equals(this.folder)) return;
274         this.folder = folder;
275         setTreeInput(folder, files);
276         initializeValues();
277         updateWidgetEnablements();
278     }
279     
280     /*
281      * Set the resource tree input to the files that were deleted
282      */

283     private void setTreeInput(IContainer folder, ICVSFile[] cvsFiles) {
284         reset();
285         IResource[] files = new IResource[cvsFiles.length];
286         for (int i = 0; i < cvsFiles.length; i++) {
287             files[i] = cvsFiles[i].getIResource();
288         }
289         treeInput.setResources(files);
290         // kludge to avoid auto-selection of first element
291
// set the root to the folder's parent so the folder appears in the tree
292
treeInput.setRoot(folder.getParent());
293         refresh();
294     }
295
296     private void reset() {
297         this.selectedFile = null;
298         this.selectedRevision = null;
299         treeInput.setResources(null);
300         filesToRestore = new HashMap JavaDoc();
301         if (fileContentPane != null && !fileContentPane.isDisposed()) {
302             fileContentPane.setInput(null);
303         }
304         updateWidgetEnablements();
305     }
306     
307     /**
308      * Method refresh.
309      */

310     private void refresh() {
311         if (folder == null) return;
312         
313         if (fileSelectionPane != null && !fileSelectionPane.isDisposed()) {
314             fileSelectionPane.setText(NLS.bind(CVSUIMessages.RestoreFromRepositoryFileSelectionPage_fileSelectionPaneTitle, new String JavaDoc[] { folder.getProject().getName() }));
315             fileSelectionPane.setImage(CompareUI.getImage(folder.getProject()));
316         }
317         
318         if (revisionSelectionPane != null && !revisionSelectionPane.isDisposed()) {
319             if (selectedFile == null) {
320                 revisionSelectionPane.setText(CVSUIMessages.RestoreFromRepositoryFileSelectionPage_emptyRevisionPane);
321                 revisionSelectionPane.setImage(null);
322             }
323         }
324         
325         // Empty the file content viewer
326
if (fileContentPane != null && !fileContentPane.isDisposed()) {
327             fileContentPane.setInput(null);
328         }
329         
330         // refresh the tree
331
if (fileTree != null) {
332             // If the parent folder is in the tree, make sure it is expanded
333
fileTree.setExpandedState(folder, true);
334             fileTree.refresh();
335         }
336         if (revisionsTable != null)
337             revisionsTable.refresh();
338     }
339     
340     /*
341      * Set the log entry table input to the fetched entries in response to a file selection
342      */

343     private void setLogEntryTableInput(ILogEntry[] entries) {
344         this.selectedRevision = null;
345         // Refresh the table so it picks up the selected entries through its content provider
346
revisionsTable.refresh();
347         // Check the previously checked entry if one exists
348
ILogEntry selectedEntry = (ILogEntry)filesToRestore.get(selectedFile);
349         if (selectedEntry != null) {
350             revisionsTable.setChecked(selectedEntry, true);
351         }
352         // Disable entries that represent deletions since they can't be loaded
353
for (int i = 0; i < entries.length; i++) {
354             ILogEntry entry = entries[i];
355             if (entry.isDeletion()) {
356                 revisionsTable.setGrayed(entry, true);
357             }
358         }
359         // Set the titlebar text for the revisions table
360
revisionSelectionPane.setText(NLS.bind(CVSUIMessages.RestoreFromRepositoryFileSelectionPage_revisionSelectionPaneTitle, new String JavaDoc[] { selectedFile.getName() }));
361         revisionSelectionPane.setImage(CompareUI.getImage(selectedFile));
362         // Clear the file content pane
363
fileContentPane.setInput(null);
364     }
365     
366     private void handleFileSelection(SelectionChangedEvent event) {
367         ISelection selection = event.getSelection();
368         if (selection == null || selection.isEmpty()) {
369             clearSelection();
370         } else {
371             if (selection instanceof IStructuredSelection) {
372                 IStructuredSelection structuredSelection = (IStructuredSelection) selection;
373                 IResource resource = (IResource)structuredSelection.getFirstElement();
374                 if (resource instanceof IFile) {
375                     handleFileSelection((IFile) resource);
376                 } else {
377                     clearSelection();
378                 }
379             }
380         }
381     }
382     
383     /**
384      * Method handleFileSelection.
385      * @param file
386      */

387     private void handleFileSelection(IFile file) {
388         if (this.selectedFile == file) return;
389         this.selectedFile = file;
390         if (entriesCache.get(file) == null) {
391             try {
392                 
393                 // First, we need to create a remote file handle so we can get the log entries
394
ICVSFolder parent = CVSWorkspaceRoot.getCVSFolderFor(file.getParent());
395                 FolderSyncInfo info = parent.getFolderSyncInfo();
396                 ICVSRepositoryLocation location = KnownRepositories.getInstance().getRepository(info.getRoot());
397                 final ICVSRemoteFile remoteFile = location.getRemoteFile(new Path(null, info.getRepository()).append(file.getName()).toString(), CVSTag.DEFAULT);
398                 
399                 // Then we need to fetch the log entries
400
getContainer().run(true, true, new IRunnableWithProgress() {
401                     public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
402                         try {
403                             // fetch the entries
404
ILogEntry[] entries = remoteFile.getLogEntries(monitor);
405                             // cache the entries with the selected file
406
entriesCache.put(selectedFile, entries);
407                         } catch (TeamException e) {
408                             throw new InvocationTargetException JavaDoc(e);
409                         }
410                     }
411                 });
412             } catch (CVSException e) {
413                 setErrorMessage(
414                     CVSUIPlugin.openError(getShell(), null, null, e, CVSUIPlugin.PERFORM_SYNC_EXEC)
415                         .getMessage());
416                 return;
417             } catch (InvocationTargetException JavaDoc e) {
418                 setErrorMessage(
419                     CVSUIPlugin.openError(getShell(), null, null, e, CVSUIPlugin.PERFORM_SYNC_EXEC)
420                         .getMessage());
421                 return;
422             } catch (InterruptedException JavaDoc e) {
423                 return;
424             }
425         }
426         
427         // Set the log table to display the entries for the selected file
428
setLogEntryTableInput(getSelectedEntries());
429     }
430
431     private ILogEntry[] getSelectedEntries() {
432         return (ILogEntry[])entriesCache.get(selectedFile);
433     }
434     
435     private IStorage getStorageFromLogEntry(final ILogEntry logEntry) {
436         final IStorage[] s = new IStorage[] { null };
437         try {
438             getContainer().run(true, true, new IRunnableWithProgress() {
439                 public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
440                     try {
441                         ICVSRemoteFile remoteFile = logEntry.getRemoteFile();
442                         s[0] = ((IResourceVariant)remoteFile).getStorage(monitor);
443                     } catch (TeamException e) {
444                         throw new InvocationTargetException JavaDoc(e);
445                     }
446                 }
447             });
448         } catch (InvocationTargetException JavaDoc e) {
449             setErrorMessage(
450                 CVSUIPlugin.openError(getShell(), null, null, e, CVSUIPlugin.PERFORM_SYNC_EXEC)
451                     .getMessage());
452             return null;
453         } catch (InterruptedException JavaDoc e) {
454             return null;
455         }
456         return s[0];
457     }
458
459     private void handleRevisionChecked(CheckStateChangedEvent event) {
460         if (event.getChecked()) {
461             revisionsTable.setCheckedElements(new Object JavaDoc[] {event.getElement()});
462             filesToRestore.put(selectedFile, event.getElement());
463         }
464         if (revisionsTable.getCheckedElements().length == 0) {
465             filesToRestore.remove(selectedFile);
466         }
467         fileTree.refresh();
468         updateWidgetEnablements();
469     }
470                 
471     /*
472      * A revision in the revision table has been selected.
473      * Populate the file contents pane with the selected log entry.
474      */

475     private void handleRevisionSelection(Widget w) {
476         if (fileContentPane != null && !fileContentPane.isDisposed()) {
477             Object JavaDoc o= w.getData();
478             if (o instanceof ILogEntry) {
479                 ILogEntry selected = (ILogEntry) o;
480                 if (this.selectedRevision == selected) return;
481                 this.selectedRevision = selected;
482                 if (selected.isDeletion()) {
483                     fileContentPane.setInput(null);
484                 } else {
485                     fileContentPane.setInput(new HistoryInput(selectedFile, selected));
486                     fileContentPane.setText(getEditionLabel(selectedFile, selected));
487                     fileContentPane.setImage(CompareUI.getImage(selectedFile));
488                 }
489             } else {
490                 fileContentPane.setInput(null);
491             }
492         }
493     }
494     /**
495      * Method getEditionLabel.
496      * @param selectedFile
497      * @param selected
498      * @return String
499      */

500     private String JavaDoc getEditionLabel(IFile selectedFile, ILogEntry selected) {
501         return NLS.bind(CVSUIMessages.RestoreFromRepositoryFileSelectionPage_fileContentPaneTitle, (new Object JavaDoc[] { selectedFile.getName(), selected.getRevision(), selectedFile.getFullPath().makeRelative().removeLastSegments(1).toString() }));
502     }
503     
504     public boolean restoreSelectedFiles() {
505         try {
506             getContainer().run(true, true, new IRunnableWithProgress() {
507                 public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
508                     try {
509                         monitor.beginTask(null, 100 * filesToRestore.size());
510                         for (Iterator JavaDoc iter = filesToRestore.keySet().iterator();iter.hasNext();) {
511                             IFile file = (IFile) iter.next();
512                             ILogEntry entry = (ILogEntry)filesToRestore.get(file);
513                             ensureParentExists(file);
514                             file.create(entry.getRemoteFile().getContents(Policy.subMonitorFor(monitor, 50)), false, Policy.subMonitorFor(monitor, 50));
515                         }
516                     } catch (TeamException e) {
517                         throw new InvocationTargetException JavaDoc(e);
518                     } catch (CoreException e) {
519                         throw new InvocationTargetException JavaDoc(e);
520                     } finally {
521                         monitor.done();
522                     }
523                 }
524             });
525         } catch (InvocationTargetException JavaDoc e) {
526             setErrorMessage(
527                 CVSUIPlugin.openError(getShell(), null, null, e, CVSUIPlugin.PERFORM_SYNC_EXEC)
528                     .getMessage());
529             return false;
530         } catch (InterruptedException JavaDoc e) {
531             return false;
532         }
533         return true;
534     }
535
536     /**
537      * Method ensureParentExists.
538      * @param file
539      */

540     private void ensureParentExists(IResource resource) throws CoreException {
541         IContainer parent = resource.getParent();
542         if (!parent.exists() && parent.getType() == IResource.FOLDER) {
543             ensureParentExists(parent);
544             ((IFolder)parent).create(false, true, null);
545         }
546     }
547
548     private void clearSelection() {
549         this.selectedFile = null;
550         this.selectedRevision = null;
551         refresh();
552     }
553 }
554
Popular Tags