KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > update > internal > ui > wizards > ReviewPage


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.update.internal.ui.wizards;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.net.MalformedURLException JavaDoc;
15 import java.net.URL JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.Arrays JavaDoc;
18 import java.util.Collection JavaDoc;
19 import java.util.HashSet JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Set JavaDoc;
23
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.core.runtime.IStatus;
27 import org.eclipse.core.runtime.NullProgressMonitor;
28 import org.eclipse.jface.dialogs.Dialog;
29 import org.eclipse.jface.dialogs.DialogPage;
30 import org.eclipse.jface.dialogs.ErrorDialog;
31 import org.eclipse.jface.dialogs.IDialogConstants;
32 import org.eclipse.jface.dialogs.IMessageProvider;
33 import org.eclipse.jface.operation.IRunnableWithProgress;
34 import org.eclipse.jface.viewers.CheckStateChangedEvent;
35 import org.eclipse.jface.viewers.ICheckStateListener;
36 import org.eclipse.jface.viewers.ISelectionChangedListener;
37 import org.eclipse.jface.viewers.ISelectionProvider;
38 import org.eclipse.jface.viewers.IStructuredSelection;
39 import org.eclipse.jface.viewers.ITreeContentProvider;
40 import org.eclipse.jface.viewers.SelectionChangedEvent;
41 import org.eclipse.jface.viewers.StructuredSelection;
42 import org.eclipse.jface.viewers.Viewer;
43 import org.eclipse.jface.viewers.ViewerFilter;
44 import org.eclipse.osgi.util.NLS;
45 import org.eclipse.swt.SWT;
46 import org.eclipse.swt.custom.BusyIndicator;
47 import org.eclipse.swt.custom.SashForm;
48 import org.eclipse.swt.events.SelectionAdapter;
49 import org.eclipse.swt.events.SelectionEvent;
50 import org.eclipse.swt.graphics.Image;
51 import org.eclipse.swt.layout.GridData;
52 import org.eclipse.swt.layout.GridLayout;
53 import org.eclipse.swt.widgets.Button;
54 import org.eclipse.swt.widgets.Composite;
55 import org.eclipse.swt.widgets.Control;
56 import org.eclipse.swt.widgets.Display;
57 import org.eclipse.swt.widgets.Label;
58 import org.eclipse.swt.widgets.Shell;
59 import org.eclipse.swt.widgets.TreeItem;
60 import org.eclipse.ui.PartInitException;
61 import org.eclipse.ui.PlatformUI;
62 import org.eclipse.ui.dialogs.PropertyDialogAction;
63 import org.eclipse.ui.forms.HyperlinkSettings;
64 import org.eclipse.ui.forms.events.HyperlinkAdapter;
65 import org.eclipse.ui.forms.events.HyperlinkEvent;
66 import org.eclipse.ui.forms.widgets.ScrolledFormText;
67 import org.eclipse.update.core.ICategory;
68 import org.eclipse.update.core.IFeature;
69 import org.eclipse.update.core.IFeatureReference;
70 import org.eclipse.update.core.IImport;
71 import org.eclipse.update.core.IIncludedFeatureReference;
72 import org.eclipse.update.core.IPluginEntry;
73 import org.eclipse.update.core.ISiteFeatureReference;
74 import org.eclipse.update.core.IURLEntry;
75 import org.eclipse.update.core.Utilities;
76 import org.eclipse.update.core.VersionedIdentifier;
77 import org.eclipse.update.internal.core.ExtendedSite;
78 import org.eclipse.update.internal.core.UpdateCore;
79 import org.eclipse.update.internal.core.UpdateManagerUtils;
80 import org.eclipse.update.internal.operations.FeatureStatus;
81 import org.eclipse.update.internal.operations.OperationValidator;
82 import org.eclipse.update.internal.operations.UpdateUtils;
83 import org.eclipse.update.internal.operations.OperationValidator.InternalImport;
84 import org.eclipse.update.internal.operations.OperationValidator.RequiredFeaturesResult;
85 import org.eclipse.update.internal.ui.UpdateUI;
86 import org.eclipse.update.internal.ui.UpdateUIImages;
87 import org.eclipse.update.internal.ui.UpdateUIMessages;
88 import org.eclipse.update.internal.ui.model.FeatureReferenceAdapter;
89 import org.eclipse.update.internal.ui.model.SimpleFeatureAdapter;
90 import org.eclipse.update.internal.ui.model.SiteBookmark;
91 import org.eclipse.update.internal.ui.model.SiteCategory;
92 import org.eclipse.update.internal.ui.parts.DefaultContentProvider;
93 import org.eclipse.update.internal.ui.parts.SWTUtil;
94 import org.eclipse.update.internal.ui.parts.SharedLabelProvider;
95 import org.eclipse.update.operations.IInstallFeatureOperation;
96 import org.eclipse.update.operations.IUpdateModelChangedListener;
97 import org.eclipse.update.operations.OperationsManager;
98 import org.eclipse.update.search.IUpdateSearchSite;
99 import org.eclipse.update.search.UpdateSearchRequest;
100
101 public class ReviewPage extends BannerPage {
102
103     private Label label;
104     private ArrayList JavaDoc jobs;
105     private Label counterLabel;
106     private IStatus validationStatus;
107     private Collection JavaDoc problematicFeatures = new HashSet JavaDoc();
108     // feature that was recently selected or null
109
private IFeature newlySelectedFeature;
110     //
111
private FeatureStatus lastDisplayedStatus;
112     private PropertyDialogAction propertiesAction;
113     private ScrolledFormText descLabel;
114     private Button statusButton;
115     private Button moreInfoButton;
116     private Button propertiesButton;
117     private Button selectRequiredFeaturesButton;
118     private Button filterCheck;
119     private Button filterOlderVersionCheck;
120     private ContainmentFilter filter = new ContainmentFilter();
121     private LatestVersionFilter olderVersionFilter = new LatestVersionFilter();
122     private UpdateSearchRequest searchRequest;
123     //private int LABEL_ORDER = 1;
124
//private int VERSION_ORDER = 1;
125
//private int PROVIDER_ORDER = 1;
126
private ContainerCheckedTreeViewer treeViewer;
127     private boolean initialized;
128     private boolean isUpdateSearch;
129   
130     
131     class TreeContentProvider extends DefaultContentProvider implements
132             ITreeContentProvider {
133
134         public Object JavaDoc[] getElements(Object JavaDoc parent) {
135             return getSites();
136         }
137
138         public Object JavaDoc[] getChildren(final Object JavaDoc parent) {
139             if (parent instanceof SiteBookmark) {
140                 SiteBookmark bookmark = (SiteBookmark) parent;
141                 bookmark.getSite(null); // triggers catalog creation
142
Object JavaDoc[] children = bookmark.getCatalog(true,null);
143                 ArrayList JavaDoc nonEmptyCategories = new ArrayList JavaDoc(children.length);
144                 for (int i=0; i<children.length; i++)
145                     if (hasChildren(children[i]))
146                         nonEmptyCategories.add(children[i]);
147                 return nonEmptyCategories.toArray();
148             } else if (parent instanceof SiteCategory) {
149                 SiteCategory category = (SiteCategory)parent;
150                 //return category.getChildren();
151
Object JavaDoc[] children = category.getChildren();
152                 ArrayList JavaDoc list = new ArrayList JavaDoc(children.length);
153                 for (int i=0; i<children.length; i++) {
154                     if (children[i] instanceof FeatureReferenceAdapter) {
155                         try {
156                             IInstallFeatureOperation job = findJob((FeatureReferenceAdapter)children[i]);
157                             if (job != null)
158                                 list.add(job);
159                         } catch (CoreException e) {
160                             UpdateCore.log(e.getStatus());
161                         }
162                     }
163                 }
164                 return list.toArray();
165             }
166             return new Object JavaDoc[0];
167         }
168
169         public Object JavaDoc getParent(Object JavaDoc element) {
170             if (element instanceof SiteCategory)
171                 return ((SiteCategory) element).getBookmark();
172             if (element instanceof IInstallFeatureOperation) {
173                 IFeature f = ((IInstallFeatureOperation)element).getFeature();
174                 ISiteFeatureReference fr = f.getSite().getFeatureReference(f);
175                 ICategory[] categories = fr.getCategories();
176 // if (categories != null && categories.length > 0)
177
// return categories[0];
178
SiteBookmark[] sites = (SiteBookmark[])((ITreeContentProvider)treeViewer.getContentProvider()).getElements(null);
179                 for (int i=0; i<sites.length; i++) {
180                     try {
181                         if (sites[i].getSite(false, null).getURL() != f.getSite().getSiteContentProvider().getURL()) {
182                             // if the site has mirrors check if this is from the mirror that user selected
183
if (sites[i].getSite(false, null) instanceof ExtendedSite) {
184                                 ExtendedSite site = (ExtendedSite)sites[i].getSite(false, null);
185                                 IURLEntry siteMirror = site.getSelectedMirror();
186                                 if (siteMirror != null && siteMirror.getURL().toExternalForm().equals(f.getSite().getSiteContentProvider().getURL().toExternalForm())) {
187                                     // this is the site so proceed with the loop
188
} else {
189                                     continue;
190                                 }
191                             } else {
192                                 continue;
193                             }
194                         }
195                     } catch (CoreException ce) {
196                         return null;
197                     }
198                     Object JavaDoc[] children = sites[i].getCatalog(true, null);
199                     for (int j = 0; j<children.length; j++) {
200                         if (!(children[j] instanceof SiteCategory))
201                             continue;
202                         for (int c=0; c < categories.length; c++)
203                             if (categories[c].getName().equals(((SiteCategory)children[j]).getName()))
204                                 return children[j];
205                     }
206                 }
207             }
208
209             return null;
210         }
211
212         public boolean hasChildren(Object JavaDoc element) {
213             return (element instanceof SiteBookmark || (
214                     element instanceof SiteCategory && getChildren(element).length > 0));
215         }
216
217         private SiteBookmark[] getSites() {
218             if (searchRequest == null)
219                 return new SiteBookmark[0];
220             else if (searchRequest.getScope().getSearchSites() == null ||
221                 searchRequest.getScope().getSearchSites().length == 0) {
222                 // this is an update search, so see if there are any jobs first,
223
// and get their sites
224
if (jobs != null) {
225                     ArrayList JavaDoc sitesList = new ArrayList JavaDoc(jobs.size());
226                     for (int i = 0; i < jobs.size(); i++) {
227                         IInstallFeatureOperation op = (IInstallFeatureOperation) jobs
228                                 .get(i);
229                         // we need a label for the site, so try to get it from the old
230
// feature update url
231
String JavaDoc label = null;
232                         IFeature[] existingFeatures = UpdateUtils
233                                 .getInstalledFeatures(op.getFeature(), true);
234                         if (existingFeatures != null
235                                 && existingFeatures.length > 0) {
236                             IURLEntry entry = op.getFeature()
237                                     .getUpdateSiteEntry();
238                             label = entry.getAnnotation();
239                         }
240                         if (label == null)
241                             label = op.getFeature().getSite().getURL().toExternalForm();
242                                     
243                         SiteBookmark bookmark = new SiteBookmark(label,
244                                 op.getFeature().getSite().getURL(), false);
245                         if (sitesList.contains(bookmark))
246                             continue;
247                         else
248                             sitesList.add(bookmark);
249                         
250                     }
251                     if (!sitesList.isEmpty())
252                         return (SiteBookmark[]) sitesList
253                                 .toArray(new SiteBookmark[sitesList.size()]);
254                 }
255                 return new SiteBookmark[0];
256             } else {
257                 // search for features
258
IUpdateSearchSite[] sites = searchRequest.getScope().getSearchSites();
259                 SiteBookmark[] siteBookmarks = new SiteBookmark[sites.length];
260                 for (int i = 0; i < sites.length; i++)
261                     siteBookmarks[i] = new SiteBookmark(sites[i].getLabel(),
262                             sites[i].getURL(), false);
263                 return siteBookmarks;
264             }
265         }
266     }
267
268     class TreeLabelProvider extends SharedLabelProvider {
269
270         public Image getImage(Object JavaDoc obj) {
271             if (obj instanceof SiteBookmark)
272                 return UpdateUI.getDefault().getLabelProvider().get(
273                         UpdateUIImages.DESC_SITE_OBJ);
274             if (obj instanceof SiteCategory)
275                 return UpdateUI.getDefault().getLabelProvider().get(
276                         UpdateUIImages.DESC_CATEGORY_OBJ);
277             if (obj instanceof IInstallFeatureOperation) {
278                 IFeature feature = ((IInstallFeatureOperation) obj).getFeature();
279                 boolean patch = feature.isPatch();
280                 
281                 //boolean problematic=problematicFeatures.contains(feature) && treeViewer.getChecked(obj);
282
boolean featureIsProblematic = isFeatureProblematic(feature);
283                 boolean problematic = treeViewer.getChecked(obj) && featureIsProblematic;
284                 
285                 if (!problematic && featureIsProblematic) {
286                     Object JavaDoc parent = ((TreeContentProvider)treeViewer.getContentProvider()).getParent(obj);
287                     problematic = treeViewer.getChecked(parent) && !treeViewer.getGrayed(parent);
288                 }
289                 
290                 if (patch) {
291                     return get(UpdateUIImages.DESC_EFIX_OBJ, problematic? F_ERROR : 0);
292                 } else {
293                     return get(UpdateUIImages.DESC_FEATURE_OBJ, problematic? F_ERROR : 0);
294                 }
295             }
296             return super.getImage(obj);
297
298         }
299
300         public String JavaDoc getText(Object JavaDoc obj) {
301             if (obj instanceof SiteBookmark)
302                 return ((SiteBookmark) obj).getLabel();
303             /*
304             if (obj instanceof SiteCategory)
305                 return obj.toString();
306                 */

307             if (obj instanceof IInstallFeatureOperation) {
308                 IInstallFeatureOperation job = (IInstallFeatureOperation) obj;
309                 IFeature feature = job.getFeature();
310                 return feature.getLabel() + " " + feature //$NON-NLS-1$
311
.getVersionedIdentifier()
312                             .getVersion()
313                             .toString();
314             }
315             return super.getText(obj);
316         }
317     }
318
319     class ModelListener implements IUpdateModelChangedListener {
320         public void objectChanged(Object JavaDoc object, String JavaDoc property) {
321             treeViewer.refresh();
322             checkItems();
323         }
324
325         public void objectsAdded(Object JavaDoc parent, Object JavaDoc[] children) {
326             treeViewer.refresh();
327             checkItems();
328         }
329
330         public void objectsRemoved(Object JavaDoc parent, Object JavaDoc[] children) {
331             treeViewer.refresh();
332             checkItems();
333         }
334         
335         private void checkItems() {
336             TreeItem[] items = treeViewer.getTree().getItems();
337             for (int i = 0; i < items.length; i++) {
338                 SiteBookmark bookmark = (SiteBookmark) items[i].getData();
339                 treeViewer.setChecked(bookmark, bookmark.isSelected());
340                 String JavaDoc[] ignoredCats = bookmark.getIgnoredCategories();
341                 treeViewer.setGrayed(bookmark, ignoredCats.length > 0
342                         && bookmark.isSelected());
343             }
344         }
345     }
346
347     class ContainmentFilter extends ViewerFilter {
348         
349         private IInstallFeatureOperation[] selectedJobs;
350         
351         public boolean select(Viewer viewer, Object JavaDoc parent, Object JavaDoc element) {
352             if (element instanceof IInstallFeatureOperation) {
353                 return !isContained((IInstallFeatureOperation) element) || isSelected( selectedJobs, (IInstallFeatureOperation)element);
354             } else if ( (element instanceof SiteCategory) || (element instanceof SiteBookmark)){
355                 Object JavaDoc[] children = ((ITreeContentProvider)((ContainerCheckedTreeViewer)viewer).getContentProvider()).getChildren(element);
356                 for ( int i = 0; i < children.length; i++) {
357                     if (select(viewer, element, children[i])) {
358                         return true;
359                     }
360                 }
361                 return false;
362             }
363         
364             return true;
365         }
366         
367         private boolean isContained(IInstallFeatureOperation job) {
368             VersionedIdentifier vid = job.getFeature().getVersionedIdentifier();
369
370             for (int i = 0; i < jobs.size(); i++) {
371                 IInstallFeatureOperation candidate = (IInstallFeatureOperation) jobs.get(i);
372                 if (candidate.equals(job))
373                     continue;
374                 IFeature feature = candidate.getFeature();
375                 if (includes(feature, vid,null))
376                     return true;
377             }
378             return false;
379         }
380         private boolean includes(IFeature feature, VersionedIdentifier vid, ArrayList JavaDoc cycleCandidates) {
381             try {
382                 if (cycleCandidates == null)
383                     cycleCandidates = new ArrayList JavaDoc();
384                 if (cycleCandidates.contains(feature))
385                     throw Utilities.newCoreException(NLS.bind(UpdateUIMessages.InstallWizard_ReviewPage_cycle, feature.getVersionedIdentifier().toString()), null);
386                 else
387                     cycleCandidates.add(feature);
388                 IFeatureReference[] irefs =
389                     feature.getIncludedFeatureReferences();
390                 for (int i = 0; i < irefs.length; i++) {
391                     IFeatureReference iref = irefs[i];
392                     IFeature ifeature = UpdateUtils.getIncludedFeature(feature, iref);
393                     VersionedIdentifier ivid =
394                         ifeature.getVersionedIdentifier();
395                     if (ivid.equals(vid))
396                         return true;
397                     if (includes(ifeature, vid, cycleCandidates))
398                         return true;
399                 }
400                 return false;
401             } catch (CoreException e) {
402                 return false;
403             } finally {
404                 // after this feature has been DFS-ed, it is no longer a cycle candidate
405
cycleCandidates.remove(feature);
406             }
407         }
408
409
410         public IInstallFeatureOperation[] getSelectedJobs() {
411             return selectedJobs;
412         }
413         
414
415         public void setSelectedJobs(IInstallFeatureOperation[] selectedJobs) {
416             this.selectedJobs = selectedJobs;
417         }
418
419     
420     }
421
422     class LatestVersionFilter extends ViewerFilter {
423         
424         private IInstallFeatureOperation[] selectedJobs;
425         
426         public boolean select(Viewer viewer, Object JavaDoc parent, Object JavaDoc element) {
427                         
428             if (element instanceof IInstallFeatureOperation) {
429                 return isLatestVersion((IInstallFeatureOperation) element) || isSelected( selectedJobs, (IInstallFeatureOperation)element);
430             } else if ( (element instanceof SiteCategory) || (element instanceof SiteBookmark)){
431                 Object JavaDoc[] children = ((ITreeContentProvider)((ContainerCheckedTreeViewer)viewer).getContentProvider()).getChildren(element);
432                 for ( int i = 0; i < children.length; i++) {
433                     if (select(viewer, element, children[i])) {
434                         return true;
435                     }
436                 }
437                 return false;
438             }
439             
440             return true;
441         }
442         
443         private boolean isLatestVersion(IInstallFeatureOperation job) {
444             IFeature feature = job.getFeature();
445             for (int i = 0; i < jobs.size(); i++) {
446                 IInstallFeatureOperation candidateJob = (IInstallFeatureOperation) jobs.get(i);
447                 if (candidateJob.equals(job))
448                     continue;
449                 IFeature candidate = candidateJob.getFeature();
450                 if (feature.getSite() != job.getFeature().getSite())
451                     continue;
452                 if (!feature.getVersionedIdentifier().getIdentifier().equals(candidate.getVersionedIdentifier().getIdentifier()))
453                     continue;
454                 if (!feature.getVersionedIdentifier().getVersion().isGreaterOrEqualTo(candidate.getVersionedIdentifier().getVersion()))
455                     return false;
456             }
457             return true;
458         }
459         
460         public IInstallFeatureOperation[] getSelectedJobs() {
461             return selectedJobs;
462         }
463         
464         public void setSelectedJobs(IInstallFeatureOperation[] selectedJobs) {
465             this.selectedJobs = selectedJobs;
466         }
467         
468         
469     }
470     
471     class FeaturePropertyDialogAction extends PropertyDialogAction {
472         private IStructuredSelection selection;
473
474         public FeaturePropertyDialogAction(
475             Shell shell,
476             ISelectionProvider provider) {
477             super(shell, provider);
478         }
479
480         public IStructuredSelection getStructuredSelection() {
481             return selection;
482         }
483
484         public void selectionChanged(IStructuredSelection selection) {
485             this.selection = selection;
486         }
487
488     }
489     /**
490      * Constructor for ReviewPage2
491      */

492     public ReviewPage(boolean isUpdateSearch, UpdateSearchRequest searchRequest, ArrayList JavaDoc jobs) {
493         super("Review"); //$NON-NLS-1$
494
this.isUpdateSearch = isUpdateSearch;
495         this.jobs = jobs;
496         if (this.jobs==null) this.jobs = new ArrayList JavaDoc();
497         this.searchRequest = searchRequest;
498         
499         setTitle(UpdateUIMessages.InstallWizard_ReviewPage_title);
500         setDescription(UpdateUIMessages.InstallWizard_ReviewPage_desc);
501         UpdateUI.getDefault().getLabelProvider().connect(this);
502         setBannerVisible(false);
503     }
504
505     public void dispose() {
506         UpdateUI.getDefault().getLabelProvider().disconnect(this);
507         super.dispose();
508     }
509
510     public void setVisible(boolean visible) {
511         super.setVisible(visible);
512         
513         // when searching for updates, only nested patches can be shown.
514
// when searching for features, features and patches can be shown
515
String JavaDoc filterText = filterCheck.getText();
516         String JavaDoc filterFeatures = UpdateUIMessages.InstallWizard_ReviewPage_filterFeatures;
517         String JavaDoc filterPatches = UpdateUIMessages.InstallWizard_ReviewPage_filterPatches;
518
519         if (isUpdateSearch && filterText.equals(filterFeatures))
520             filterCheck.setText(filterPatches);
521         else if ( !isUpdateSearch && filterText.equals(filterPatches))
522             filterCheck.setText(filterFeatures);
523         
524         if (visible && !initialized) {
525             initialized = true;
526 // jobs.clear();
527

528 // setDescription(UpdateUI.getString("InstallWizard.ReviewPage.searching")); //$NON-NLS-1$;
529
// label.setText(UpdateUI.getString("")); //$NON-NLS-1$
530

531             getShell().getDisplay().asyncExec(new Runnable JavaDoc() {
532                 public void run() {
533 // searchRunner.runSearch();
534
performPostSearchProcessing();
535                 }
536             });
537         }
538     }
539
540     private void performPostSearchProcessing() {
541         BusyIndicator.showWhile(getShell().getDisplay(), new Runnable JavaDoc() {
542             public void run() {
543                 if (treeViewer != null) {
544 // treeViewer.refresh();
545
// treeViewer.getTree().layout(true);
546
if (isUpdateSearch) {
547                         selectTrueUpdates();
548                     }
549                 }
550                 pageChanged();
551                 
552                 int totalCount = jobs != null ? jobs.size(): 0;
553                 if(totalCount >0) {
554                     setDescription(UpdateUIMessages.InstallWizard_ReviewPage_desc);
555                     label.setText(UpdateUIMessages.InstallWizard_ReviewPage_label);
556                 } else {
557                     if (isUpdateSearch)
558                         setDescription(UpdateUIMessages.InstallWizard_ReviewPage_zeroUpdates);
559                     else
560                         setDescription(UpdateUIMessages.InstallWizard_ReviewPage_zeroFeatures);
561                     label.setText(""); //$NON-NLS-1$
562
}
563             }
564         });
565     }
566     
567     private void selectTrueUpdates() {
568         ArrayList JavaDoc trueUpdates = new ArrayList JavaDoc();
569         for (int i=0; i<jobs.size(); i++) {
570             IInstallFeatureOperation job = (IInstallFeatureOperation)jobs.get(i);
571             if (!UpdateUtils.isPatch(job.getFeature()))
572                 trueUpdates.add(job);
573         }
574         treeViewer.setCheckedElements(trueUpdates.toArray());
575         validateSelection(new NullProgressMonitor());
576     }
577
578     /**
579      * @see DialogPage#createControl(Composite)
580      */

581     public Control createContents(Composite parent) {
582         Composite client = new Composite(parent, SWT.NULL);
583         GridLayout layout = new GridLayout();
584         layout.numColumns = 2;
585         layout.marginWidth = layout.marginHeight = 0;
586         client.setLayout(layout);
587         label = new Label(client, SWT.NULL);
588         label.setText(UpdateUIMessages.InstallWizard_ReviewPage_label);
589         GridData gd = new GridData();
590         gd.horizontalSpan = 2;
591         label.setLayoutData(gd);
592
593         createTreeViewer(client);
594
595         Composite comp = new Composite(client, SWT.NONE);
596         layout = new GridLayout();
597         layout.marginWidth = layout.marginHeight = 0;
598         comp.setLayout(layout);
599         comp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
600                 
601         Composite buttonContainer = new Composite(comp, SWT.NULL);
602         gd = new GridData(GridData.FILL_VERTICAL);
603         buttonContainer.setLayoutData(gd);
604         layout = new GridLayout();
605         layout.marginWidth = 0;
606         layout.marginHeight = 0; //30?
607
buttonContainer.setLayout(layout);
608         buttonContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
609
610         Button button = new Button(buttonContainer, SWT.PUSH);
611         button.setText(UpdateUIMessages.InstallWizard_ReviewPage_deselectAll);
612         gd =
613             new GridData(
614                 GridData.HORIZONTAL_ALIGN_FILL
615                     | GridData.VERTICAL_ALIGN_BEGINNING);
616         button.setLayoutData(gd);
617         SWTUtil.setButtonDimensionHint(button);
618         button.addSelectionListener(new SelectionAdapter() {
619             public void widgetSelected(SelectionEvent e) {
620                 handleDeselectAll();
621             }
622         });
623
624         moreInfoButton = new Button(buttonContainer, SWT.PUSH);
625         moreInfoButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_moreInfo);
626         gd =
627             new GridData(
628                 GridData.HORIZONTAL_ALIGN_FILL
629                     | GridData.VERTICAL_ALIGN_BEGINNING);
630         moreInfoButton.setLayoutData(gd);
631         SWTUtil.setButtonDimensionHint(moreInfoButton);
632         moreInfoButton.addSelectionListener(new SelectionAdapter() {
633             public void widgetSelected(SelectionEvent e) {
634                 handleMoreInfo();
635             }
636         });
637         moreInfoButton.setEnabled(false);
638         
639         
640         propertiesButton = new Button(buttonContainer, SWT.PUSH);
641         propertiesButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_properties);
642         gd =
643             new GridData(
644                 GridData.HORIZONTAL_ALIGN_FILL
645                     | GridData.VERTICAL_ALIGN_BEGINNING);
646         propertiesButton.setLayoutData(gd);
647         SWTUtil.setButtonDimensionHint(propertiesButton);
648         propertiesButton.addSelectionListener(new SelectionAdapter() {
649             public void widgetSelected(SelectionEvent e) {
650                 handleProperties();
651             }
652         });
653         propertiesButton.setEnabled(false);
654
655         selectRequiredFeaturesButton = new Button(buttonContainer, SWT.PUSH);
656         selectRequiredFeaturesButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_selectRequired);
657         gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL
658                 | GridData.VERTICAL_ALIGN_BEGINNING);
659         selectRequiredFeaturesButton.setLayoutData(gd);
660         SWTUtil.setButtonDimensionHint(selectRequiredFeaturesButton);
661         selectRequiredFeaturesButton
662                 .addSelectionListener(new SelectionAdapter() {
663                     public void widgetSelected(SelectionEvent e) {
664                         BusyIndicator.showWhile(e.display, new Runnable JavaDoc() {
665                             public void run() {
666                                 selectRequiredFeatures();
667                                 updateItemCount();
668                             }
669                         });
670                     }
671                 });
672
673         statusButton = new Button(buttonContainer, SWT.PUSH);
674         statusButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_showStatus);
675         gd =
676             new GridData(
677                 GridData.HORIZONTAL_ALIGN_FILL
678                     | GridData.VERTICAL_ALIGN_BEGINNING);
679         statusButton.setLayoutData(gd);
680         SWTUtil.setButtonDimensionHint(statusButton);
681         statusButton.addSelectionListener(new SelectionAdapter() {
682             public void widgetSelected(SelectionEvent e) {
683                 showStatus();
684             }
685         });
686
687         //new Label(client, SWT.NULL);
688

689         counterLabel = new Label(client, SWT.NULL);
690         gd = new GridData();
691         gd.horizontalSpan = 2;
692         counterLabel.setLayoutData(gd);
693
694         filterOlderVersionCheck = new Button(client, SWT.CHECK);
695         filterOlderVersionCheck.setText(UpdateUIMessages.InstallWizard_ReviewPage_filterOlderFeatures);
696         filterOlderVersionCheck.setSelection(true);
697         treeViewer.addFilter(olderVersionFilter);
698         filterOlderVersionCheck.addSelectionListener(new SelectionAdapter() {
699             public void widgetSelected(SelectionEvent e) {
700
701                 IInstallFeatureOperation[] jobs = getSelectedJobs();
702                 
703                 if (filterOlderVersionCheck.getSelection())
704                     treeViewer.addFilter(olderVersionFilter);
705                 else
706                     treeViewer.removeFilter(olderVersionFilter);
707                 
708                 olderVersionFilter.setSelectedJobs(jobs);
709                 pageChanged(jobs);
710             }
711         });
712         gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
713         gd.horizontalSpan = 2;
714         filterOlderVersionCheck.setLayoutData(gd);
715         
716         filterCheck = new Button(client, SWT.CHECK);
717         filterCheck.setText(UpdateUIMessages.InstallWizard_ReviewPage_filterFeatures);
718         filterCheck.setSelection(false);
719         //tableViewer.addFilter(filter);
720
filterCheck.addSelectionListener(new SelectionAdapter() {
721             public void widgetSelected(SelectionEvent e) {
722                 
723                 IInstallFeatureOperation[] jobs = getSelectedJobs();
724                 
725                 if (filterCheck.getSelection()) {
726                     // make sure model is local
727
if (downloadIncludedFeatures()) {
728                         treeViewer.addFilter(filter);
729                     } else {
730                         filterCheck.setSelection(false);
731                     }
732                 } else {
733                     treeViewer.removeFilter(filter);
734                 }
735                 
736                 filter.setSelectedJobs(jobs);
737                 
738                 pageChanged(jobs);
739             }
740         });
741         gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
742         gd.horizontalSpan = 2;
743         filterCheck.setLayoutData(gd);
744         
745         pageChanged();
746
747         PlatformUI.getWorkbench().getHelpSystem().setHelp(client, "org.eclipse.update.ui.MultiReviewPage2"); //$NON-NLS-1$
748

749         Dialog.applyDialogFont(parent);
750
751         return client;
752     }
753
754     private void createTreeViewer(final Composite parent) {
755         SashForm sform = new SashForm(parent, SWT.VERTICAL);
756         GridData gd = new GridData(GridData.FILL_BOTH);
757         gd.widthHint = 250;
758         gd.heightHint =100;
759         sform.setLayoutData(gd);
760         
761         treeViewer = new ContainerCheckedTreeViewer(sform, SWT.H_SCROLL | SWT.V_SCROLL
762                 | SWT.BORDER);
763         treeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
764         treeViewer.setContentProvider(new TreeContentProvider());
765         treeViewer.setLabelProvider(new TreeLabelProvider());
766         treeViewer.setInput(UpdateUI.getDefault().getUpdateModel());
767
768         treeViewer
769             .addSelectionChangedListener(new ISelectionChangedListener() {
770             public void selectionChanged(SelectionChangedEvent e) {
771                 handleSelectionChanged((IStructuredSelection) e.getSelection());
772             }
773         });
774         
775         treeViewer.addCheckStateListener(new ICheckStateListener() {
776             public void checkStateChanged(CheckStateChangedEvent event) {
777                 /*
778                  * validateSelection(); Object site =
779                  * getSite(event.getElement()); ArrayList descendants = new
780                  * ArrayList(); collectDescendants(site, descendants); Object[]
781                  * nodes = new Object[descendants.size()]; for (int i = 0; i <
782                  * nodes.length; i++) nodes[i] = descendants.get(i);
783                  * treeViewer.update(nodes, null); updateItemCount();
784                  */

785                 try {
786                     getContainer().run(true, true,
787                             getCheckStateOperation(event, parent.getDisplay()));
788                     getContainer().updateButtons();
789                     updateStatusButton();
790                 } catch (InvocationTargetException JavaDoc e) {
791                     UpdateUI.logException(e);
792                 } catch (InterruptedException JavaDoc e) {
793                     UpdateUI.logException(e);
794                 }
795             }
796         });
797         
798       descLabel = new ScrolledFormText(sform, true);
799       descLabel.setText(""); //$NON-NLS-1$
800
descLabel.setBackground(parent.getBackground());
801       HyperlinkSettings settings = new HyperlinkSettings(parent.getDisplay());
802       descLabel.getFormText().setHyperlinkSettings(settings);
803       descLabel.getFormText().addHyperlinkListener(new HyperlinkAdapter() {
804           public void linkActivated(HyperlinkEvent e) {
805               Object JavaDoc href = e.getHref();
806               if (href==null)
807                   return;
808               try {
809                   URL JavaDoc url = new URL JavaDoc(href.toString());
810                   PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(url);
811               }
812               catch (PartInitException ex) {
813                   UpdateUI.logException(ex);
814               }
815               catch (MalformedURLException JavaDoc ex) {
816                   UpdateUI.logException(ex);
817               }
818           }
819       });
820       
821       gd = new GridData(SWT.FILL, SWT.FILL, true, true);
822       gd.horizontalSpan = 1;
823       descLabel.setLayoutData(gd);
824       
825       sform.setWeights(new int[] {10, 2});
826     }
827     
828     private IRunnableWithProgress getCheckStateOperation(
829             final CheckStateChangedEvent event, final Display display) {
830         return new IRunnableWithProgress() {
831             public void run(IProgressMonitor monitor) {
832                 monitor.beginTask(UpdateUIMessages.ReviewPage_validating,
833                         IProgressMonitor.UNKNOWN);
834                 validateSelection(monitor);
835                 if (monitor.isCanceled()) {
836                     undoStateChange(event);
837                     monitor.done();
838                     return;
839                 }
840                 Object JavaDoc site = getSite(event.getElement());
841                 ArrayList JavaDoc descendants = new ArrayList JavaDoc();
842                 collectDescendants(site, descendants, monitor);
843                 final Object JavaDoc[] nodes = new Object JavaDoc[descendants.size()];
844                 if (monitor.isCanceled()) {
845                     undoStateChange(event);
846                     monitor.done();
847                     return;
848                 }
849                 for (int i = 0; i < nodes.length; i++)
850                     nodes[i] = descendants.get(i);
851                 display.syncExec(new Runnable JavaDoc() {
852                     public void run() {
853                         treeViewer.update(nodes, null);
854                         updateItemCount();
855                     }
856                 });
857                 monitor.done();
858             }
859         };
860     }
861     
862     private void undoStateChange(final CheckStateChangedEvent e) {
863         treeViewer.getControl().getDisplay().syncExec(new Runnable JavaDoc() {
864             public void run() {
865                 treeViewer.setChecked(e.getElement(), !e.getChecked());
866             }
867         });
868     }
869     
870     private void handleSelectionChanged(IStructuredSelection ssel) {
871         
872         Object JavaDoc item = ssel.getFirstElement();
873         String JavaDoc description = null;
874         if (item instanceof SiteBookmark) {
875             description = ((SiteBookmark)item).getDescription();
876         } else if (item instanceof SiteCategory) {
877             IURLEntry descEntry = ((SiteCategory)item).getCategory().getDescription();
878             if (descEntry != null)
879                 description = descEntry.getAnnotation();
880         } else if (item instanceof IInstallFeatureOperation) {
881             jobSelected(ssel);
882             return;
883         }
884
885         if (description == null)
886             description = ""; //$NON-NLS-1$
887
//descLabel.setText(UpdateManagerUtils.getWritableXMLString(description), false, true);
888
updateDescription(description);
889         propertiesButton.setEnabled(false);
890         moreInfoButton.setEnabled(false);
891     }
892
893 /*
894     private void fillContextMenu(IMenuManager manager) {
895         if (treeViewer.getSelection().isEmpty()) return;
896         Action action = new Action(UpdateUIMessages.InstallWizard_ReviewPage_prop) {
897             public void run() {
898                 handleProperties();
899             }
900         };
901         manager.add(action);
902     }
903 */

904
905     private void jobSelected(IStructuredSelection selection) {
906         IInstallFeatureOperation job = (IInstallFeatureOperation) selection.getFirstElement();
907         IFeature feature = job != null ? job.getFeature() : null;
908         IURLEntry descEntry = feature != null ? feature.getDescription() : null;
909         String JavaDoc desc = null;
910         if (descEntry != null)
911             desc = descEntry.getAnnotation();
912         if (desc == null)
913             desc = ""; //$NON-NLS-1$
914
//descLabel.setText(UpdateManagerUtils.getWritableXMLString(desc));
915
updateDescription(desc);
916         propertiesButton.setEnabled(feature != null);
917         moreInfoButton.setEnabled(job != null && getMoreInfoURL(job) != null);
918     }
919     
920     private void updateDescription(String JavaDoc text) {
921         descLabel.getFormText().setText(UpdateManagerUtils.getWritableXMLString(text), false, true);
922         descLabel.reflow(true);
923     }
924     
925     private void pageChanged() {
926         pageChanged(this.getSelectedJobs());
927     }
928     
929     private void pageChanged( IInstallFeatureOperation[] jobsSelected) {
930     
931         if (jobsSelected.length == 0) {
932             lastDisplayedStatus = null;
933             setErrorMessage(null);
934             setPageComplete(false);
935             setValidationStatus(null);
936             problematicFeatures.clear();
937         }
938         treeViewer.setCheckedElements(jobsSelected);
939         //validateSelection();
940
treeViewer.refresh();
941         treeViewer.setCheckedElements(jobsSelected);
942         updateItemCount();
943     }
944     
945     private void setValidationStatus(IStatus newValidationStatus) {
946         this.validationStatus = newValidationStatus;
947         updateStatusButton();
948     }
949     
950     private void updateStatusButton() {
951         statusButton.getDisplay().syncExec(new Runnable JavaDoc() {
952             public void run() {
953                 boolean newState = validationStatus != null && validationStatus.getSeverity() != IStatus.OK;
954                 statusButton.setEnabled(newState);
955             }
956         });
957     }
958     
959     private void updateItemCount() {
960         updateItemCount(-1, -1);
961     }
962     
963     private int getSelectedJobsUniqueCount() {
964         Object JavaDoc[] checkedElements = getSelectedJobs();
965         Set JavaDoc set = new HashSet JavaDoc();
966         for (int i=0; i<checkedElements.length; i++) {
967             IInstallFeatureOperation job = (IInstallFeatureOperation)checkedElements[i];
968             IFeature feature = job.getFeature();
969             if (set.contains(feature))
970                 continue;
971             set.add(feature);
972         }
973         return set.size();
974     }
975
976     private void updateItemCount(int checkedCount, int totalCount) {
977         if (checkedCount == -1) {
978             checkedCount = getSelectedJobsUniqueCount();
979         }
980         if (totalCount == -1) {
981             totalCount = jobs.size();
982         }
983         String JavaDoc total = "" + totalCount; //$NON-NLS-1$
984
String JavaDoc selected = "" + checkedCount; //$NON-NLS-1$
985
counterLabel.setText(
986             NLS.bind(UpdateUIMessages.InstallWizard_ReviewPage_counter, (new String JavaDoc[] { selected, total })));
987         counterLabel.getParent().layout();
988     }
989
990 // private void handleSelectAll(boolean select) {
991
// treeViewer.setAllChecked(select);
992
//// make sure model is local (download using progress monitor from container)
993
// downloadIncludedFeatures();
994
//
995
// treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
996
// public void run() {
997
// pageChanged();
998
// }
999
// });
1000
// }
1001

1002// private void handleSelectAll(boolean select) {
1003
// treeViewer.setAllChecked(select);
1004
//// make sure model is local (download using progress monitor from container)
1005
// downloadIncludedFeatures();
1006
//
1007
// treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
1008
// public void run() {
1009
// pageChanged();
1010
// }
1011
// });
1012
//}
1013

1014   private void handleDeselectAll() {
1015        //treeViewer.setCheckedElements(new Object[0]);
1016
IInstallFeatureOperation[] selectedJobs = getSelectedJobs();
1017         for( int i = 0; i < selectedJobs.length; i++)
1018             treeViewer.setChecked( selectedJobs[i], false);
1019        // make sure model is local (download using progress monitor from
1020
// container)
1021
// downloadIncludedFeatures();
1022

1023        treeViewer.getControl().getDisplay().asyncExec(new Runnable JavaDoc() {
1024            public void run() {
1025                pageChanged();
1026            }
1027        });
1028}
1029    
1030    private void handleProperties() {
1031        final IStructuredSelection selection =
1032            (IStructuredSelection) treeViewer.getSelection();
1033
1034        final IInstallFeatureOperation job =
1035            (IInstallFeatureOperation) selection.getFirstElement();
1036        if (propertiesAction == null) {
1037            propertiesAction =
1038                new FeaturePropertyDialogAction(getShell(), treeViewer);
1039        }
1040
1041        BusyIndicator
1042            .showWhile(treeViewer.getControl().getDisplay(), new Runnable JavaDoc() {
1043            public void run() {
1044                SimpleFeatureAdapter adapter =
1045                    new SimpleFeatureAdapter(job.getFeature());
1046                propertiesAction.selectionChanged(
1047                    new StructuredSelection(adapter));
1048                propertiesAction.run();
1049            }
1050        });
1051    }
1052
1053    private String JavaDoc getMoreInfoURL(IInstallFeatureOperation job) {
1054        IURLEntry desc = job.getFeature().getDescription();
1055        if (desc != null) {
1056            URL JavaDoc url = desc.getURL();
1057            return (url == null) ? null : url.toString();
1058        }
1059        return null;
1060    }
1061
1062    private void handleMoreInfo() {
1063        IStructuredSelection selection =
1064            (IStructuredSelection) treeViewer.getSelection();
1065        final IInstallFeatureOperation selectedJob =
1066            (IInstallFeatureOperation) selection.getFirstElement();
1067        BusyIndicator
1068            .showWhile(treeViewer.getControl().getDisplay(), new Runnable JavaDoc() {
1069            public void run() {
1070                String JavaDoc urlName = getMoreInfoURL(selectedJob);
1071                UpdateUI.showURL(urlName);
1072            }
1073        });
1074    }
1075
1076    private IStatus selectRequiredFeatures() {
1077        
1078        IInstallFeatureOperation[] jobs = getSelectedJobs();
1079        RequiredFeaturesResult requiredFeaturesResult = ((OperationValidator)OperationsManager
1080                .getValidator()).getRequiredFeatures(jobs);
1081        setValidationStatus(requiredFeaturesResult.getStatus());
1082        Set JavaDoc requiredFeatures = requiredFeaturesResult.getRequiredFeatures();
1083        problematicFeatures.clear();
1084        
1085        Iterator JavaDoc requiredFeaturesIterator = requiredFeatures.iterator();
1086        ArrayList JavaDoc toBeInstalled = new ArrayList JavaDoc();
1087        
1088        while (requiredFeaturesIterator.hasNext()) {
1089            IImport requiredFeature = ((InternalImport)requiredFeaturesIterator.next()).getImport();
1090
1091            IInstallFeatureOperation currentFeatureSelected = null;
1092            TreeItem[] items = treeViewer.getTree().getItems();
1093            for (int i = 0; i < items.length; i++) {
1094                TreeItem[] siteRootContent = items[i].getItems();
1095                for (int j = 0; j < siteRootContent.length; j++) {
1096                    if (siteRootContent[j].getData() instanceof SiteCategory) {
1097                        
1098                        if ( !treeViewer.getChecked(siteRootContent[j].getData())) {
1099                            // this category has not been checked at all so we have to create its features
1100
treeViewer.createChildren(siteRootContent[j]);
1101                        }
1102                        TreeItem[] features = siteRootContent[j].getItems();
1103                        if ((features.length > 0) && (features[0].getData() == null)) {
1104                            // this category has been checked but not visited yet so restore the features in it
1105
treeViewer.createChildren(siteRootContent[j]);
1106                            treeViewer.updateChildrenItems(siteRootContent[j]);
1107                            features = siteRootContent[j].getItems();
1108                        }
1109                        
1110                        for (int k = 0; k < features.length; k++) {
1111                            currentFeatureSelected = decideOnFeatureSelection(
1112                                    requiredFeature,
1113                                    (IInstallFeatureOperation) features[k]
1114                                            .getData(), currentFeatureSelected);
1115                        }
1116                    } else if (siteRootContent[j].getData() instanceof IInstallFeatureOperation) {
1117                        currentFeatureSelected = decideOnFeatureSelection(
1118                                requiredFeature,
1119                                (IInstallFeatureOperation) siteRootContent[j]
1120                                        .getData(), currentFeatureSelected);
1121                    }
1122                }
1123            }
1124
1125            if (currentFeatureSelected != null)
1126                toBeInstalled.add(currentFeatureSelected);
1127        }
1128
1129        if (!toBeInstalled.isEmpty()) {
1130            Iterator JavaDoc toBeInstalledIterator = toBeInstalled.iterator();
1131            while (toBeInstalledIterator.hasNext()) {
1132                IInstallFeatureOperation current = (IInstallFeatureOperation)toBeInstalledIterator.next();
1133                treeViewer.setChecked(current, true);
1134            }
1135            return selectRequiredFeatures();
1136        } else {
1137            problematicFeatures.clear();
1138            if (validationStatus != null) {
1139                IStatus[] status = validationStatus.getChildren();
1140                for (int i = 0; i < status.length; i++) {
1141                    IStatus singleStatus = status[i];
1142                    if (isSpecificStatus(singleStatus)) {
1143                        IFeature f = ((FeatureStatus) singleStatus)
1144                                .getFeature();
1145                        problematicFeatures.add(f);
1146                    }
1147                }
1148            }
1149
1150            setPageComplete(validationStatus == null
1151                    || validationStatus.getSeverity() == IStatus.WARNING);
1152
1153            lastDisplayedStatus = null;
1154            updateWizardMessage();
1155            
1156            treeViewer.update(getSelectedJobs(), null);
1157            return validationStatus;
1158        }
1159    }
1160
1161    public IInstallFeatureOperation[] getSelectedJobs() {
1162        Object JavaDoc[] selected = treeViewer.getCheckedElements();
1163        ArrayList JavaDoc selectedJobs = new ArrayList JavaDoc(selected.length);
1164        for (int i=0; i<selected.length; i++)
1165            if (selected[i] instanceof IInstallFeatureOperation)
1166                selectedJobs.add(selected[i]);
1167        return (IInstallFeatureOperation[])selectedJobs.toArray(new IInstallFeatureOperation[selectedJobs.size()]);
1168    }
1169    
1170    public void validateSelection(IProgressMonitor monitor) {
1171        IInstallFeatureOperation[] jobs;
1172
1173        final IInstallFeatureOperation[][] bag = new IInstallFeatureOperation[1][];
1174        treeViewer.getControl().getDisplay().syncExec(new Runnable JavaDoc() {
1175            public void run() {
1176                bag[0] = getSelectedJobs();
1177            }
1178        });
1179        if (monitor.isCanceled()) return;
1180        jobs = bag[0];
1181        setValidationStatus(OperationsManager.getValidator()
1182                .validatePendingChanges(jobs));
1183        problematicFeatures.clear();
1184        if (monitor.isCanceled()) return;
1185        if (validationStatus != null) {
1186            IStatus[] status = validationStatus.getChildren();
1187            for (int i = 0; i < status.length; i++) {
1188                IStatus singleStatus = status[i];
1189                if (isSpecificStatus(singleStatus)) {
1190                    IFeature f = ((FeatureStatus) singleStatus).getFeature();
1191                    problematicFeatures.add(f);
1192                }
1193            }
1194        }
1195        if (monitor.isCanceled())
1196                return;
1197        treeViewer.getControl().getDisplay().syncExec(new Runnable JavaDoc() {
1198            public void run() {
1199                setPageComplete(validationStatus == null
1200                        || validationStatus.getSeverity() == IStatus.WARNING);
1201/*
1202                statusButton.setEnabled(validationStatus != null
1203                        && validationStatus.getSeverity() != IStatus.OK);
1204                        */

1205
1206                updateWizardMessage();
1207            }
1208        });
1209    }
1210
1211    private void showStatus() {
1212        if (validationStatus != null) {
1213            new StatusDialog().open();
1214        }
1215
1216    }
1217    /**
1218     * Check whether status is relevant to show for
1219     * a specific feature or is a other problem
1220     * @param status
1221     * @return true if status is FeatureStatus with
1222     * specified feature and certain error codes
1223     */

1224    private boolean isSpecificStatus(IStatus status){
1225        if(!(status instanceof FeatureStatus)){
1226            return false;
1227        }
1228        if(status.getSeverity()!=IStatus.ERROR){
1229            return false;
1230        }
1231        FeatureStatus featureStatus = (FeatureStatus) status;
1232        if(featureStatus.getFeature()==null){
1233            return false;
1234        }
1235        return 0!= (featureStatus.getCode()
1236                & FeatureStatus.CODE_CYCLE
1237                + FeatureStatus.CODE_ENVIRONMENT
1238                + FeatureStatus.CODE_EXCLUSIVE
1239                + FeatureStatus.CODE_OPTIONAL_CHILD
1240                + FeatureStatus.CODE_PREREQ_FEATURE
1241                + FeatureStatus.CODE_PREREQ_PLUGIN);
1242    }
1243    /**
1244     * Update status in the wizard status area
1245     */

1246    private void updateWizardMessage() {
1247        
1248        if (validationStatus == null) {
1249            lastDisplayedStatus=null;
1250            setErrorMessage(null);
1251        } else if (validationStatus.getSeverity() == IStatus.WARNING) {
1252            lastDisplayedStatus=null;
1253            setErrorMessage(null);
1254            setMessage(validationStatus.getMessage(), IMessageProvider.WARNING);
1255        } else {
1256            // 1. Feature selected, creating a problem for it, show status for it
1257
if(newlySelectedFeature !=null){
1258                IStatus[] status = validationStatus.getChildren();
1259                for(int s =0; s< status.length; s++){
1260                    if(isSpecificStatus(status[s])){
1261                        FeatureStatus featureStatus = (FeatureStatus)status[s];
1262                        if(newlySelectedFeature.equals(featureStatus.getFeature())){
1263                            lastDisplayedStatus=featureStatus;
1264                            setErrorMessage(featureStatus.getMessage());
1265                            return;
1266                        }
1267                    }
1268                }
1269            }
1270            
1271            // 2. show old status if possible (it is still valid)
1272
if(lastDisplayedStatus !=null){
1273                IStatus[] status = validationStatus.getChildren();
1274                for(int i=0; i<status.length; i++){
1275                    if(lastDisplayedStatus.equals(status[i])){
1276                        //lastDisplayedStatus=lastDisplayedStatus;
1277
//setErrorMessage(status[i].getMessage());
1278
return;
1279                    }
1280                }
1281                lastDisplayedStatus = null;
1282            }
1283            
1284            // 3. pick the first problem that is specific to some feature
1285
IStatus[] status = validationStatus.getChildren();
1286            for(int s =0; s< status.length; s++){
1287                if(isSpecificStatus(status[s])){
1288                    lastDisplayedStatus = (FeatureStatus)status[s];
1289                    setErrorMessage(status[s].getMessage());
1290                    return;
1291                }
1292            }
1293                
1294            // 4. display the first problem (no problems specify a feature)
1295
if(status.length>0){
1296                IStatus singleStatus=status[0];
1297                setErrorMessage(singleStatus.getMessage());
1298            }else{
1299            // 5. not multi or empty multi status
1300
setErrorMessage(UpdateUIMessages.InstallWizard_ReviewPage_invalid_long);
1301            }
1302        }
1303    }
1304
1305    class StatusDialog extends ErrorDialog {
1306// Button detailsButton;
1307
public StatusDialog() {
1308            super(getContainer().getShell(), UpdateUIMessages.InstallWizard_ReviewPage_invalid_short, null,
1309                    validationStatus, IStatus.OK | IStatus.INFO
1310                            | IStatus.WARNING | IStatus.ERROR);
1311        }
1312// protected Button createButton(
1313
// Composite parent,
1314
// int id,
1315
// String label,
1316
// boolean defaultButton) {
1317
// Button b = super.createButton(parent, id, label, defaultButton);
1318
// if(IDialogConstants.DETAILS_ID == id){
1319
// detailsButton = b;
1320
// }
1321
// return b;
1322
// }
1323
public void create() {
1324            super.create();
1325            buttonPressed(IDialogConstants.DETAILS_ID);
1326// if(detailsButton!=null){
1327
// detailsButton.dispose();
1328
// }
1329
}
1330    }
1331
1332    /**
1333     * @return true, if completed, false if canceled by the user
1334     */

1335    private boolean downloadIncludedFeatures() {
1336        try {
1337            Downloader downloader = new Downloader(jobs);
1338            getContainer().run(true, true, downloader);
1339            return !downloader.isCanceled();
1340        } catch (InvocationTargetException JavaDoc ite) {
1341        } catch (InterruptedException JavaDoc ie) {
1342        }
1343        return true;
1344    }
1345    /**
1346     * Runnable to resolve included feature references.
1347     */

1348    class Downloader implements IRunnableWithProgress {
1349        boolean canceled = false;
1350        /**
1351         * List of IInstallFeatureOperation
1352         */

1353        ArrayList JavaDoc operations;
1354        public Downloader(ArrayList JavaDoc installOperations) {
1355            operations = installOperations;
1356        }
1357        public boolean isCanceled() {
1358            return canceled;
1359        }
1360        public void run(IProgressMonitor monitor)
1361                throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
1362            for (int i = 0; i < operations.size(); i++) {
1363                IInstallFeatureOperation candidate = (IInstallFeatureOperation) operations
1364                        .get(i);
1365                IFeature feature = candidate.getFeature();
1366                try {
1367                    IFeatureReference[] irefs = feature
1368                            .getRawIncludedFeatureReferences();
1369                    for (int f = 0; f < irefs.length; f++) {
1370                        if (monitor.isCanceled()) {
1371                            canceled = true;
1372                            return;
1373                        }
1374                        IFeatureReference iref = irefs[f];
1375                        iref.getFeature(monitor);
1376                    }
1377                } catch (CoreException e) {
1378                }
1379            }
1380            if (monitor.isCanceled()) {
1381                canceled = true;
1382            }
1383        }
1384    }
1385    
1386    private IInstallFeatureOperation findJob(FeatureReferenceAdapter feature)
1387            throws CoreException {
1388        if (jobs == null)
1389            return null;
1390        for (int i = 0; i < jobs.size(); i++)
1391            if (((IInstallFeatureOperation) jobs.get(i)).getFeature()
1392                    .getVersionedIdentifier().equals(feature.getFeatureReference()
1393                    .getVersionedIdentifier()))
1394                return (IInstallFeatureOperation) jobs.get(i);
1395
1396        return null;
1397    }
1398    
1399    private Object JavaDoc getSite(Object JavaDoc object) {
1400        ITreeContentProvider provider = (ITreeContentProvider)treeViewer.getContentProvider();
1401        while (object != null && !(object instanceof SiteBookmark)) {
1402            object = provider.getParent(object);
1403        }
1404        return object;
1405    }
1406    
1407    private void collectDescendants(Object JavaDoc root, ArrayList JavaDoc list,
1408            IProgressMonitor monitor) {
1409        ITreeContentProvider provider = (ITreeContentProvider) treeViewer
1410                .getContentProvider();
1411        Object JavaDoc[] children = provider.getChildren(root);
1412        if (children != null && children.length > 0)
1413            for (int i = 0; i < children.length; i++) {
1414                if (monitor.isCanceled())
1415                    return;
1416                list.add(children[i]);
1417                collectDescendants(children[i], list, monitor);
1418            }
1419    }
1420
1421    
1422    public boolean isFeatureGood(IImport requiredFeature, IFeature feature) {
1423        return isFeatureGood(requiredFeature, feature, new ArrayList JavaDoc());
1424    }
1425    
1426    public boolean isFeatureGood(IImport prereq, IFeature feature, List JavaDoc visitedFeatures) {
1427
1428        if (prereq.getKind() == IImport.KIND_FEATURE) {
1429            if ((!prereq.getVersionedIdentifier().getIdentifier().equals(
1430                    feature.getVersionedIdentifier().getIdentifier()))) {
1431                IIncludedFeatureReference[] iifr = null;
1432                try {
1433                    iifr = feature.getIncludedFeatureReferences();
1434                } catch (CoreException e) {
1435                    UpdateUI.logException(e);
1436                    // if we can not get included features then they can not satisfy requirement, so just ignore them
1437
return false;
1438                }
1439                if (iifr == null) {
1440                    return false;
1441                }
1442                
1443                for(int i = 0; i < iifr.length; i++) {
1444                    IFeature current;
1445                    try {
1446                        current = UpdateUtils.getIncludedFeature(feature, iifr[i]);
1447                    } catch (CoreException e) {
1448                        // if we can not get feature then it can not satisfy requirement, so just ignore it
1449
UpdateUI.logException(e);
1450                        continue;
1451                    }
1452                    if (!visitedFeatures.contains(current)) {
1453                        visitedFeatures.add(current);
1454                        if (isFeatureGood(prereq, current, visitedFeatures)) {
1455                            return true;
1456                        }
1457                    }
1458                }
1459                
1460                return false;
1461            }
1462
1463            int rule = (prereq.getRule() != IImport.RULE_NONE) ? prereq.getRule() : IImport.RULE_COMPATIBLE;
1464
1465            switch (rule) {
1466            case IImport.RULE_PERFECT: return feature.getVersionedIdentifier().getVersion().isPerfect(
1467                                prereq.getVersionedIdentifier()
1468                                .getVersion());
1469            case IImport.RULE_EQUIVALENT:
1470                        return feature.getVersionedIdentifier().getVersion()
1471                        .isEquivalentTo(
1472                                prereq.getVersionedIdentifier()
1473                                .getVersion());
1474            case IImport.RULE_COMPATIBLE:
1475                return feature.getVersionedIdentifier().getVersion()
1476                        .isCompatibleWith(
1477                                prereq.getVersionedIdentifier()
1478                                .getVersion());
1479            case IImport.RULE_GREATER_OR_EQUAL:
1480                        return feature.getVersionedIdentifier().getVersion()
1481                        .isGreaterOrEqualTo(
1482                                prereq.getVersionedIdentifier()
1483                                .getVersion());
1484            }
1485
1486            return false;
1487        } else {
1488            if ((prereq.getKind() == IImport.KIND_PLUGIN)) {
1489                return checkIfFeatureHasPlugin( prereq, feature);
1490            }
1491            return false;
1492        }
1493    }
1494    
1495    private boolean checkIfFeatureHasPlugin(IImport requiredFeature, IFeature feature) {
1496        
1497        IPluginEntry[] plugins = feature.getPluginEntries();
1498        try {
1499            List JavaDoc includedPlugins = getPluginEntriesFromIncludedFeatures(feature, new ArrayList JavaDoc(), new ArrayList JavaDoc());
1500            includedPlugins.addAll(Arrays.asList(plugins));
1501            plugins = (IPluginEntry[])includedPlugins.toArray( new IPluginEntry[includedPlugins.size()]);
1502        } catch( CoreException ce) {
1503            UpdateUI.logException(ce);
1504            // ignore this plugins can not sutisfy requirement anyways
1505
}
1506        if (plugins == null) {
1507            return false;
1508        }
1509        
1510        for(int i = 0; i < plugins.length; i++) {
1511            if (isMatch(plugins[i].getVersionedIdentifier(), requiredFeature.getVersionedIdentifier(), requiredFeature.getIdRule())) {
1512                return true;
1513            }
1514        }
1515        
1516        return false;
1517    }
1518
1519    private List JavaDoc getPluginEntriesFromIncludedFeatures(IFeature feature, List JavaDoc plugins, List JavaDoc visitedFeatures) throws CoreException {
1520        IIncludedFeatureReference[] iifr = feature.getIncludedFeatureReferences();
1521        for(int i = 0; i < iifr.length; i++) {
1522            IFeature current = UpdateUtils.getIncludedFeature( feature, iifr[i]);
1523            if (!visitedFeatures.contains(current)) {
1524                IPluginEntry[] pluginEntries = current.getPluginEntries();
1525                plugins.addAll(Arrays.asList(pluginEntries));
1526                visitedFeatures.add(current);
1527                getPluginEntriesFromIncludedFeatures(current, plugins, visitedFeatures);
1528            }
1529        }
1530        
1531        return plugins;
1532    }
1533
1534    // vid1 = feature
1535
// vid2 = requiredFeature
1536
private boolean isMatch( VersionedIdentifier vid1, VersionedIdentifier vid2, int rule) {
1537        
1538        if (!vid1.getIdentifier().equals(vid2.getIdentifier())) {
1539            return false;
1540        }
1541        if ( vid2.getVersion().getMajorComponent() == 0 && vid2.getVersion().getMinorComponent() == 0 && vid2.getVersion().getServiceComponent() == 0 ) {
1542            //version is ignored
1543
return true;
1544        }
1545        switch (rule) {
1546        case IImport.RULE_PERFECT:
1547            return vid1.getVersion().isPerfect(vid2.getVersion());
1548        case IImport.RULE_EQUIVALENT:
1549            return vid1.getVersion().isEquivalentTo(vid2.getVersion());
1550        case IImport.RULE_COMPATIBLE:
1551            return vid1.getVersion().isCompatibleWith(vid2.getVersion());
1552        case IImport.RULE_GREATER_OR_EQUAL:
1553            return vid1.getVersion().isGreaterOrEqualTo(vid2.getVersion());
1554        }
1555        return false;
1556    }
1557
1558    public boolean isFeatureBetter(IInstallFeatureOperation feature,
1559            IInstallFeatureOperation currentFeatureSelected) {
1560
1561        if (currentFeatureSelected == null)
1562            return true;
1563        // If the feature is the same, pick the newer one
1564
if (currentFeatureSelected.getFeature().getVersionedIdentifier().getIdentifier().equals(
1565                feature.getFeature().getVersionedIdentifier().getIdentifier())) {
1566            return !currentFeatureSelected.getFeature().getVersionedIdentifier()
1567            .getVersion().isGreaterOrEqualTo(
1568                    feature.getFeature().getVersionedIdentifier()
1569                            .getVersion());
1570        }
1571        else {
1572            // Different features.
1573
// Pick a feature with smaller number of plug-ins
1574
NullProgressMonitor monitor = new NullProgressMonitor();
1575            int currentNumber = getTotalNumberOfPluginEntries(currentFeatureSelected.getFeature(), monitor);
1576            int newNumber = getTotalNumberOfPluginEntries(feature.getFeature(), monitor);
1577            return newNumber<currentNumber;
1578        }
1579    }
1580    
1581    private int getTotalNumberOfPluginEntries(IFeature feature, IProgressMonitor monitor) {
1582        int count = 0;
1583        try {
1584            count = feature.getPluginEntryCount();
1585            IIncludedFeatureReference [] irefs = feature.getIncludedFeatureReferences();
1586            for (int i=0; i<irefs.length; i++) {
1587                IFeature child = irefs[i].getFeature(monitor);
1588                count += getTotalNumberOfPluginEntries(child, monitor);
1589            }
1590        }
1591        catch (CoreException e) {
1592        }
1593        return count;
1594    }
1595
1596    public IInstallFeatureOperation decideOnFeatureSelection(
1597            IImport requiredFeature, IInstallFeatureOperation feature,
1598            IInstallFeatureOperation currentFeatureSelected) {
1599
1600        if (isFeatureGood(requiredFeature, feature.getFeature()) && isFeatureBetter(feature, currentFeatureSelected)) {
1601                return feature;
1602        } else {
1603            return currentFeatureSelected;
1604        }
1605    }
1606    
1607    private boolean isFeatureProblematic(IFeature feature) {
1608        
1609        if ( problematicFeatures.contains(feature) )
1610            return true;
1611        
1612        IImport[] iimports = feature.getImports();
1613        
1614        for(int i = 0; i < iimports.length; i++) {
1615            Iterator JavaDoc problematicFeatures = this.problematicFeatures.iterator();
1616            while(problematicFeatures.hasNext()) {
1617                if (iimports[i].getVersionedIdentifier().equals( ((IFeature)problematicFeatures.next()).getVersionedIdentifier()) ) {
1618                    return true;
1619                }
1620            }
1621        }
1622        try {
1623            Iterator JavaDoc includedFeatures = OperationValidator.computeFeatureSubtree(feature, null, null, false, new ArrayList JavaDoc(), null ).iterator();
1624            while (includedFeatures.hasNext()) {
1625                Iterator JavaDoc problematicFeatures = this.problematicFeatures.iterator();
1626                VersionedIdentifier currentIncludedFeaturesVI = ((IFeature)includedFeatures.next()).getVersionedIdentifier();
1627                while (problematicFeatures.hasNext()) {
1628                    Object JavaDoc currentProblematicFeatures = problematicFeatures.next();
1629                    if (currentProblematicFeatures instanceof IFeature) {
1630                        VersionedIdentifier currentProblematicFeaturesVI = ((IFeature)currentProblematicFeatures).getVersionedIdentifier();
1631                        if (currentProblematicFeaturesVI.equals( currentIncludedFeaturesVI) ) {
1632                            return true;
1633                        }
1634                    }
1635                }
1636            }
1637        } catch (CoreException ce) {
1638        }
1639        return false;
1640    }
1641    
1642    private boolean isSelected( IInstallFeatureOperation[] selectedJobs, IInstallFeatureOperation iInstallFeatureOperation) {
1643        
1644        if (selectedJobs == null)
1645            return false;
1646        
1647        for( int i = 0; i < selectedJobs.length; i++) {
1648            
1649            if (iInstallFeatureOperation.getFeature().getVersionedIdentifier().equals(selectedJobs[i].getFeature().getVersionedIdentifier()) &&
1650                iInstallFeatureOperation.getFeature().getSite().getURL().equals(selectedJobs[i].getFeature().getSite().getURL())) {
1651                return true;
1652            }
1653        }
1654        
1655        return false;
1656    }
1657}
1658
Popular Tags