KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > versioning > system > cvss > ui > history > DiffResultsView


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.versioning.system.cvss.ui.history;
21
22 import org.netbeans.lib.cvsclient.command.log.LogInformation;
23 import org.netbeans.modules.versioning.system.cvss.util.Utils;
24 import org.netbeans.modules.versioning.system.cvss.ui.actions.diff.DiffStreamSource;
25 import org.netbeans.modules.versioning.system.cvss.VersionsCache;
26 import org.netbeans.modules.versioning.util.NoContentPanel;
27 import org.netbeans.api.diff.DiffView;
28 import org.netbeans.api.diff.Diff;
29 import org.openide.explorer.ExplorerManager;
30 import org.openide.nodes.Node;
31 import org.openide.util.NbBundle;
32 import org.openide.util.RequestProcessor;
33 import org.openide.util.Cancellable;
34 import org.openide.ErrorManager;
35
36 import javax.swing.*;
37 import javax.swing.event.AncestorListener JavaDoc;
38 import javax.swing.event.AncestorEvent JavaDoc;
39 import java.util.*;
40 import java.util.List JavaDoc;
41 import java.beans.PropertyChangeListener JavaDoc;
42 import java.beans.PropertyChangeEvent JavaDoc;
43 import java.io.IOException JavaDoc;
44 import java.awt.*;
45
46 /**
47  * Shows Search History results in a table with Diff pane below it.
48  *
49  * @author Maros Sandor
50  */

51 class DiffResultsView implements AncestorListener JavaDoc, PropertyChangeListener JavaDoc {
52
53     private final SearchHistoryPanel parent;
54
55     private DiffTreeTable treeView;
56     private JSplitPane diffView;
57     
58     private ShowDiffTask currentTask;
59     private RequestProcessor.Task currentShowDiffTask;
60     
61     private DiffView currentDiff;
62     private int currentDifferenceIndex;
63     private int currentIndex;
64     private boolean dividerSet;
65
66     public DiffResultsView(SearchHistoryPanel parent, List JavaDoc results) {
67         this.parent = parent;
68         treeView = new DiffTreeTable();
69         treeView.setResults(results);
70         treeView.addAncestorListener(this);
71
72         diffView = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
73         diffView.setTopComponent(treeView);
74         setBottomComponent(new NoContentPanel(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_NoRevisions"))); // NOI18N
75
}
76
77     public void ancestorAdded(AncestorEvent JavaDoc event) {
78         ExplorerManager em = ExplorerManager.find(treeView);
79         em.addPropertyChangeListener(this);
80         if (!dividerSet) {
81             SwingUtilities.invokeLater(new Runnable JavaDoc() {
82                 public void run() {
83                     dividerSet = true;
84                     diffView.setDividerLocation(0.33);
85                 }
86             });
87         }
88     }
89
90     public void ancestorMoved(AncestorEvent JavaDoc event) {
91     }
92
93     public void ancestorRemoved(AncestorEvent JavaDoc event) {
94         ExplorerManager em = ExplorerManager.find(treeView);
95         em.removePropertyChangeListener(this);
96         cancelBackgroundTasks();
97     }
98
99     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
100         if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
101             final Node [] nodes = (Node[]) evt.getNewValue();
102             currentDifferenceIndex = 0;
103             if (nodes.length == 0) {
104                 showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_NoRevisions")); // NOI18N
105
parent.refreshComponents(false);
106                 return;
107             }
108             else if (nodes.length > 2) {
109                 showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_TooManyRevisions")); // NOI18N
110
parent.refreshComponents(false);
111                 return;
112             }
113
114             // invoked asynchronously becase treeView.getSelection() may not be ready yet
115
Runnable JavaDoc runnable = new Runnable JavaDoc() {
116                 public void run() {
117                     if (treeView.getSelection().length == 0) return;
118                     SearchHistoryPanel.ResultsContainer container1 = nodes[0].getLookup().lookup(SearchHistoryPanel.ResultsContainer.class);
119                     SearchHistoryPanel.DispRevision r1 = nodes[0].getLookup().lookup(SearchHistoryPanel.DispRevision.class);
120                     try {
121                         if (r1 == null || !r1.isBranchRoot()) {
122                             currentIndex = treeView.getSelection()[0];
123                             if (nodes.length == 1) {
124                                 if (container1 != null) {
125                                     showContainerDiff(container1, onSelectionshowLastDifference);
126                                 }
127                                 else if (r1 != null) {
128                                     showRevisionDiff(r1, onSelectionshowLastDifference);
129                                 }
130                             } else if (nodes.length == 2) {
131                                 SearchHistoryPanel.DispRevision r2 = nodes[1].getLookup().lookup(SearchHistoryPanel.DispRevision.class);
132                                 if (r2.isBranchRoot()) throw new Exception JavaDoc();
133                                 if (r2.getRevision().getLogInfoHeader() != r1.getRevision().getLogInfoHeader()) {
134                                     throw new Exception JavaDoc();
135                                 }
136                                 String JavaDoc revision1 = r1.getRevision().getNumber();
137                                 String JavaDoc revision2 = r2.getRevision().getNumber();
138                                 if (SearchHistoryPanel.compareRevisions(revision1, revision2) == 1) {
139                                     revision2 = r1.getRevision().getNumber();
140                                     revision1 = r2.getRevision().getNumber();
141                                 }
142                                 showDiff(r1.getRevision().getLogInfoHeader(), revision1, revision2, false);
143                             }
144                         } else {
145                             showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_IllegalSelection")); // NOI18N
146
}
147                     } catch (Exception JavaDoc e) {
148                         showDiffError(NbBundle.getMessage(DiffResultsView.class, "MSG_DiffPanel_IllegalSelection")); // NOI18N
149
parent.refreshComponents(false);
150                         return;
151                     }
152                 }
153             };
154             SwingUtilities.invokeLater(runnable);
155         }
156     }
157
158     private void showDiffError(String JavaDoc s) {
159         setBottomComponent(new NoContentPanel(s));
160     }
161
162     private void setBottomComponent(Component component) {
163         int dl = diffView.getDividerLocation();
164         diffView.setBottomComponent(component);
165         diffView.setDividerLocation(dl);
166     }
167
168     private void showDiff(LogInformation header, String JavaDoc revision1, String JavaDoc revision2, boolean showLastDifference) {
169         synchronized(this) {
170             cancelBackgroundTasks();
171             currentTask = new ShowDiffTask(header, revision1, revision2, showLastDifference);
172             currentShowDiffTask = RequestProcessor.getDefault().create(currentTask);
173             currentShowDiffTask.schedule(0);
174         }
175     }
176
177     private synchronized void cancelBackgroundTasks() {
178         if (currentShowDiffTask != null && !currentShowDiffTask.isFinished()) {
179             currentShowDiffTask.cancel(); // it almost always late it's enqueued, so:
180
currentTask.cancel();
181         }
182     }
183
184     private boolean onSelectionshowLastDifference;
185
186     private void setDiffIndex(int idx, boolean showLastDifference) {
187         currentIndex = idx;
188         onSelectionshowLastDifference = showLastDifference;
189         treeView.setSelection(idx);
190     }
191
192     private void showRevisionDiff(SearchHistoryPanel.DispRevision rev, boolean showLastDifference) {
193         String JavaDoc revision2 = rev.getRevision().getNumber();
194         String JavaDoc revision1;
195         if (revision2 == VersionsCache.REVISION_CURRENT) {
196             SearchHistoryPanel.ResultsContainer container = findParent(rev);
197             SearchHistoryPanel.DispRevision newest = container.getRevisions().get(1);
198             revision1 = newest.getRevision().getNumber();
199         } else {
200             revision1 = Utils.previousRevision(revision2);
201         }
202         showDiff(rev.getRevision().getLogInfoHeader(), revision1, revision2, showLastDifference);
203     }
204
205     private SearchHistoryPanel.ResultsContainer findParent(SearchHistoryPanel.DispRevision rev) {
206         List JavaDoc results = parent.getDispResults();
207         for (Object JavaDoc o : results) {
208             if (o instanceof SearchHistoryPanel.ResultsContainer) {
209                 SearchHistoryPanel.ResultsContainer container = (SearchHistoryPanel.ResultsContainer) o;
210                 if (container.getRevisions().contains(rev)) return container;
211             }
212         }
213         return null;
214     }
215
216     private void showContainerDiff(SearchHistoryPanel.ResultsContainer container, boolean showLastDifference) {
217         List JavaDoc revs = container.getRevisions();
218         SearchHistoryPanel.DispRevision newest = (SearchHistoryPanel.DispRevision) revs.get(1);
219         showDiff(newest.getRevision().getLogInfoHeader(), container.getEldestRevision(), newest.getRevision().getNumber(), showLastDifference);
220     }
221
222     void onNextButton() {
223         if (currentDiff != null) {
224             if (++currentDifferenceIndex >= currentDiff.getDifferenceCount()) {
225                 if (++currentIndex >= treeView.getRowCount()) currentIndex = 0;
226                 setDiffIndex(currentIndex, false);
227             } else {
228                 currentDiff.setCurrentDifference(currentDifferenceIndex);
229             }
230         } else {
231             if (++currentIndex >= treeView.getRowCount()) currentIndex = 0;
232             setDiffIndex(currentIndex, false);
233         }
234     }
235
236     void onPrevButton() {
237         if (currentDiff != null) {
238             if (--currentDifferenceIndex < 0) {
239                 if (--currentIndex < 0) currentIndex = treeView.getRowCount() - 1;
240                 setDiffIndex(currentIndex, true);
241             } else {
242                 currentDiff.setCurrentDifference(currentDifferenceIndex);
243             }
244         } else {
245             if (--currentIndex < 0) currentIndex = treeView.getRowCount() - 1;
246             setDiffIndex(currentIndex, true);
247         }
248     }
249
250     boolean isNextEnabled() {
251         if (currentDiff != null) {
252             return currentIndex < treeView.getRowCount() - 1 || currentDifferenceIndex < currentDiff.getDifferenceCount() - 1;
253         } else {
254             return false;
255         }
256     }
257
258     boolean isPrevEnabled() {
259         return currentIndex > 0 || currentDifferenceIndex > 0;
260     }
261     
262     /**
263      * Selects given revision in the view as if done by the user.
264      *
265      * @param revision revision to select
266      */

267     void select(SearchHistoryPanel.DispRevision revision) {
268         treeView.requestFocusInWindow();
269         treeView.setSelection(revision);
270     }
271
272     void select(SearchHistoryPanel.ResultsContainer container) {
273         treeView.requestFocusInWindow();
274         treeView.setSelection(container);
275     }
276
277     /**
278      * @return Collection<Object> currently selected items in the view or an empty Collection.
279      */

280     List JavaDoc<Object JavaDoc> getSelection() {
281         Node [] nodes = ExplorerManager.find(treeView).getSelectedNodes();
282         List JavaDoc<Object JavaDoc> selection = new ArrayList<Object JavaDoc>(nodes.length);
283         for (Node node : nodes) {
284             RevisionNode rnode = (RevisionNode) node;
285             if (rnode.getContainer() != null) {
286                 selection.add(rnode.getContainer());
287             } else {
288                 selection.add(rnode.getDispRevision());
289             }
290         }
291         return selection;
292     }
293
294     private class ShowDiffTask implements Runnable JavaDoc, Cancellable {
295         
296         private final LogInformation header;
297         private final String JavaDoc revision1;
298         private final String JavaDoc revision2;
299         private boolean showLastDifference;
300         private volatile boolean cancelled;
301         private Thread JavaDoc thread;
302
303         public ShowDiffTask(LogInformation header, String JavaDoc revision1, String JavaDoc revision2, boolean showLastDifference) {
304             this.header = header;
305             this.revision1 = revision1;
306             this.revision2 = revision2;
307             this.showLastDifference = showLastDifference;
308         }
309
310         public void run() {
311             thread = Thread.currentThread();
312             final Diff diff = Diff.getDefault();
313             final DiffStreamSource s1 = new DiffStreamSource(header.getFile(), revision1, revision1 == VersionsCache.REVISION_CURRENT ?
314                     NbBundle.getMessage(DiffResultsView.class, "LBL_DiffPanel_LocalCopy") : revision1); // NOI18N
315
final DiffStreamSource s2 = new DiffStreamSource(header.getFile(), revision2, revision2 == VersionsCache.REVISION_CURRENT ?
316                     NbBundle.getMessage(DiffResultsView.class, "LBL_DiffPanel_LocalCopy") : revision2); // NOI18N
317

318             // it's enqueued at ClientRuntime queue and does not return until previous request handled
319
s1.getMIMEType(); // triggers s1.init()
320
if (cancelled) {
321                 return;
322             }
323
324             s2.getMIMEType(); // triggers s2.init()
325
if (cancelled) {
326                 return;
327             }
328
329             if (currentTask != this) return;
330
331             SwingUtilities.invokeLater(new Runnable JavaDoc() {
332                 public void run() {
333                     try {
334                         if (cancelled) {
335                             return;
336                         }
337                         final DiffView view = diff.createDiff(s1, s2);
338                         if (currentTask == ShowDiffTask.this) {
339                             currentDiff = view;
340                             setBottomComponent(currentDiff.getComponent());
341                             if (currentDiff.getDifferenceCount() > 0) {
342                                 currentDifferenceIndex = showLastDifference ? currentDiff.getDifferenceCount() - 1 : 0;
343                                 currentDiff.setCurrentDifference(currentDifferenceIndex);
344                             }
345                             parent.refreshComponents(false);
346                         }
347                     } catch (IOException JavaDoc e) {
348                         ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
349                     }
350                 }
351             });
352         }
353
354         public boolean cancel() {
355             cancelled = true;
356             if (thread != null) {
357                 thread.interrupt();
358             }
359             return true;
360         }
361     }
362     
363     public JComponent getComponent() {
364         return diffView;
365     }
366 }
367
368
Popular Tags