Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 245f6e405378ebfec8bd521b40b97dba40a2a0d1 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                                                 
                   
                      
                               
                                  
                                                         
                                                         

                                                                                
                                                 
                                                                
                                                           




                                                        


                                                         
                                   


                                               

                                 









                                                                                         































































                                                                                              

                                                   



                                      
                         
                                                                                                    


















                                                                                        



                                      












                                                                                        
                                                                                      

                                                                               
                                                                                                                                                                                                                








                                                     








                                                                                                   


                                                      
                              






                                                                                    
                                                 
 
                              
 
                                      
 
                                     


                                                                 
                                                     


                              


                                     
 


                                                       
 
                                                                                                                                           









                                                                        
                                                                       












                                                                                             
                                                                               




                                                                                         
                                                                           
                                                                          
                                                                                                                                                                                                            





                                                                          
                                                                                    
                                               

                                                                                                                                      
                 
                                                                                    










                                                                                                                                                                     





















































                                                                                               
                                           





                                                                                                     


                                                                     





                                                                                                       
                                                                                                             

























                                                                                                                     







                                                                                                                                              














                                                                               

                                                          





                                               



                                                                    
                                                    






































                                                                                                                          
                                                                              
                                                             




                                                                                                                                                                  
                 
                                

         



                                                     











                                                                               



                                           

















                                                              
                                                                                       














                                                                                             
                                                                                                                                            



































                                                                                         







                                                                         

                                             
                                         


                                                                             
                                                                                                       













                                                                                                  
                                                                                                                                           
                                                



                                                                                                                                
                                        




                                                                   
                                                               


                                                                                                              
                                                                                           




                                                                                                                                         
                                                                                                                                                
                                                        













                                                                                           
 
 
/*******************************************************************************
 * Copyright (c) 2009 Tasktop Technologies and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.ui.discovery.wizards;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.discovery.Catalog;
import org.eclipse.equinox.internal.p2.discovery.model.*;
import org.eclipse.equinox.internal.p2.discovery.util.CatalogCategoryComparator;
import org.eclipse.equinox.internal.p2.discovery.util.CatalogItemComparator;
import org.eclipse.equinox.internal.p2.ui.ProvUI;
import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryUi;
import org.eclipse.equinox.internal.p2.ui.discovery.util.*;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.equinox.p2.ui.ProvisioningUI;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.statushandlers.StatusManager;

/**
 * The main wizard page that allows users to select connectors that they wish to install.
 * 
 * @author David Green
 * @author Steffen Pingel
 */
public class CatalogViewer extends FilteredViewer {

	protected static class CatalogContentProvider implements ITreeContentProvider {

		private Catalog catalog;

		private boolean hasCategories;

		public boolean hasCategories() {
			return hasCategories;
		}

		public void setHasCategories(boolean hasCategories) {
			this.hasCategories = hasCategories;
		}

		public void dispose() {
			catalog = null;
		}

		public Catalog getCatalog() {
			return catalog;
		}

		public Object[] getChildren(Object parentElement) {
			if (parentElement instanceof CatalogCategory) {
				return ((CatalogCategory) parentElement).getItems().toArray();
			}
			return null;
		}

		public Object[] getElements(Object inputElement) {
			if (catalog != null) {
				List<Object> elements = new ArrayList<Object>();
				if (hasCategories()) {
					elements.addAll(catalog.getCategories());
				}
				elements.addAll(catalog.getItems());
				return elements.toArray(new Object[0]);
			}
			return new Object[0];
		}

		public Object getParent(Object element) {
			if (element instanceof CatalogCategory) {
				return catalog;
			}
			if (element instanceof CatalogItem) {
				return ((CatalogItem) element).getCategory();
			}
			return null;
		}

		public boolean hasChildren(Object element) {
			if (element instanceof CatalogCategory) {
				return ((CatalogCategory) element).getItems().size() > 0;
			}
			return false;
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			this.catalog = (Catalog) newInput;
		}

	}

	private class Filter extends ViewerFilter {

		public Filter() {
			// constructor
		}

		@Override
		public boolean select(Viewer filteredViewer, Object parentElement, Object element) {
			if (element instanceof CatalogItem) {
				return doFilter((CatalogItem) element);
			} else if (element instanceof CatalogCategory) {
				// only show categories if at least one child is visible
				CatalogCategory category = (CatalogCategory) element;
				for (CatalogItem item : category.getItems()) {
					if (doFilter(item)) {
						return true;
					}
				}
				return false;
			}
			return true;
		}

	}

	private class FindFilter extends PatternFilter {

		public FindFilter() {
			// constructor
		}

		private boolean filterMatches(String text) {
			return text != null && wordMatches(text);
		}

		@Override
		protected Object[] getChildren(Object element) {
			if (element instanceof CatalogCategory) {
				return ((CatalogCategory) element).getItems().toArray();
			}
			return super.getChildren(element);
		}

		@Override
		protected boolean isLeafMatch(Viewer filteredViewer, Object element) {
			if (element instanceof CatalogItem) {
				CatalogItem descriptor = (CatalogItem) element;
				if (!(filterMatches(descriptor.getName()) || filterMatches(descriptor.getDescription()) || filterMatches(descriptor.getProvider()) || filterMatches(descriptor.getLicense()))) {
					return false;
				}
				return true;
			}
			return false;
		}

	}

	//	private class ConnectorBorderPaintListener implements PaintListener {
	//		public void paintControl(PaintEvent e) {
	//			Composite composite = (Composite) e.widget;
	//			Rectangle bounds = composite.getBounds();
	//			GC gc = e.gc;
	//			gc.setLineStyle(SWT.LINE_DOT);
	//			gc.drawLine(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y);
	//		}
	//	}

	private static final int DEFAULT_HEIGHT = 250;

	final Catalog catalog;

	private final List<CatalogItem> checkedItems = new ArrayList<CatalogItem>();

	private boolean complete;

	private final CatalogConfiguration configuration;

	protected final IRunnableContext context;

	boolean ignoreUpdates;

	Set<String> installedFeatures;

	DiscoveryResources resources;

	private final SelectionProviderAdapter selectionProvider;

	protected final IShellProvider shellProvider;

	boolean showInstalled;

	Button showInstalledCheckbox;

	Set<Tag> visibleTags;

	private boolean showCategories;

	private CatalogContentProvider contentProvider;

	public CatalogViewer(Catalog catalog, IShellProvider shellProvider, IRunnableContext context, CatalogConfiguration configuration) {
		Assert.isNotNull(catalog);
		Assert.isNotNull(shellProvider);
		Assert.isNotNull(context);
		Assert.isNotNull(configuration);
		this.catalog = catalog;
		this.shellProvider = shellProvider;
		this.context = context;
		this.configuration = configuration;
		this.selectionProvider = new SelectionProviderAdapter();
		this.showInstalled = configuration.isShowInstalled();
		this.showCategories = configuration.isShowCategories();
		if (configuration.getSelectedTags() != null) {
			this.visibleTags = new HashSet<Tag>(configuration.getSelectedTags());
		} else {
			this.visibleTags = new HashSet<Tag>();
		}
		setMinimumHeight(DEFAULT_HEIGHT);
		setComplete(false);
	}

	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		selectionProvider.addSelectionChangedListener(listener);
	}

	protected void catalogUpdated(boolean wasCancelled, boolean wasError) {
		if (catalog != null && !wasCancelled) {
			int categoryWithConnectorCount = 0;
			for (CatalogCategory category : catalog.getCategories()) {
				categoryWithConnectorCount += category.getItems().size();
			}
			if (categoryWithConnectorCount == 0 && !wasError) {
				// nothing was discovered: notify the user
				MessageDialog.openWarning(getShell(), Messages.ConnectorDiscoveryWizardMainPage_noConnectorsFound, Messages.ConnectorDiscoveryWizardMainPage_noConnectorsFound_description);
			}
		}
		viewer.setInput(catalog);
		selectionProvider.setSelection(StructuredSelection.EMPTY);
	}

	private IStatus computeStatus(InvocationTargetException e, String message) {
		Throwable cause = e.getCause();
		if (cause.getMessage() != null) {
			message = NLS.bind(Messages.ConnectorDiscoveryWizardMainPage_message_with_cause, message, cause.getMessage());
		}
		return new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN, message, e);
	}

	protected Pattern createPattern(String filterText) {
		if (filterText == null || filterText.length() == 0) {
			return null;
		}
		String regex = filterText;
		regex.replace("\\", "\\\\").replace("?", ".").replace("*", ".*?"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
		return Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
	}

	@Override
	protected PatternFilter doCreateFilter() {
		return new FindFilter();
	}

	@Override
	protected void doCreateHeaderControls(Composite parent) {
		if (configuration.isShowInstalledFilter()) {
			showInstalledCheckbox = new Button(parent, SWT.CHECK);
			showInstalledCheckbox.setSelection(showInstalled);
			showInstalledCheckbox.setText(Messages.DiscoveryViewer_Show_Installed);
			showInstalledCheckbox.addSelectionListener(new SelectionListener() {

				public void widgetDefaultSelected(SelectionEvent e) {
					widgetSelected(e);
				}

				public void widgetSelected(SelectionEvent e) {
					if (ignoreUpdates) {
						return;
					}

					ignoreUpdates = true;
					setShowInstalled(showInstalledCheckbox.getSelection());
					ignoreUpdates = false;
				}
			});
		}
		if (configuration.isShowTagFilter()) {
			for (final Tag tag : catalog.getTags()) {
				final Button checkbox = new Button(parent, SWT.CHECK);
				checkbox.setSelection(visibleTags.contains(tag));
				checkbox.setText(tag.getLabel());
				checkbox.addSelectionListener(new SelectionListener() {
					public void widgetDefaultSelected(SelectionEvent e) {
						widgetSelected(e);
					}

					public void widgetSelected(SelectionEvent e) {
						boolean selection = checkbox.getSelection();
						if (selection) {
							visibleTags.add(tag);
						} else {
							visibleTags.remove(tag);
						}
						refresh();
					}
				});
			}
		}
	}

	@Override
	protected StructuredViewer doCreateViewer(Composite container) {
		@SuppressWarnings("hiding")
		StructuredViewer viewer = new ControlListViewer(container, SWT.BORDER) {
			@Override
			protected ControlListItem<?> doCreateItem(Composite parent, Object element) {
				return doCreateViewerItem(parent, element);
			}
		};
		contentProvider = doCreateContentProvider();
		contentProvider.setHasCategories(isShowCategories());
		viewer.setContentProvider(contentProvider);
		viewer.setSorter(new ViewerSorter() {
			CatalogCategoryComparator categoryComparator = new CatalogCategoryComparator();

			CatalogItemComparator itemComparator = new CatalogItemComparator();

			@Override
			public int compare(@SuppressWarnings("hiding") Viewer viewer, Object o1, Object o2) {
				CatalogCategory cat1 = getCategory(o1);
				CatalogCategory cat2 = getCategory(o2);

				// FIXME filter uncategorized items?
				if (cat1 == null) {
					return (cat2 != null) ? 1 : 0;
				} else if (cat2 == null) {
					return 1;
				}

				int i = categoryComparator.compare(cat1, cat2);
				if (i == 0) {
					if (o1 instanceof CatalogCategory) {
						return -1;
					}
					if (o2 instanceof CatalogCategory) {
						return 1;
					}
					if (cat1 == cat2 && o1 instanceof CatalogItem && o2 instanceof CatalogItem) {
						return itemComparator.compare((CatalogItem) o1, (CatalogItem) o2);
					}
					return super.compare(viewer, o1, o2);
				}
				return i;
			}

			//					private int compare(Comparator<Object> comparator, Object key1, Object key2) {
			//						if (key1 == null) {
			//							return (key2 != null) ? 1 : 0;
			//						} else if (key2 == null) {
			//							return -1;
			//						}
			//						return comparator.compare(key1, key2);
			//					}
			private CatalogCategory getCategory(Object o) {
				if (o instanceof CatalogCategory) {
					return (CatalogCategory) o;
				}
				if (o instanceof CatalogItem) {
					return ((CatalogItem) o).getCategory();
				}
				return null;
			}
		});

		resources = new DiscoveryResources(container.getDisplay());
		viewer.getControl().addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				resources.dispose();
				if (catalog != null)
					catalog.dispose();
			}
		});
		viewer.addFilter(new Filter());
		return viewer;
	}

	protected CatalogContentProvider doCreateContentProvider() {
		return new CatalogContentProvider();
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	protected ControlListItem<?> doCreateViewerItem(Composite parent, Object element) {
		if (element instanceof CatalogItem) {
			return new DiscoveryItem(parent, SWT.NONE, resources, shellProvider, (CatalogItem) element, this);
		} else if (element instanceof CatalogCategory) {
			return new CategoryItem(parent, SWT.NONE, resources, (CatalogCategory) element);
		}
		return null;
	}

	protected boolean doFilter(CatalogItem item) {
		if (!showInstalled && item.isInstalled()) {
			return false;
		}

		if (!isTagVisible(item)) {
			return false;
		}

		for (CatalogFilter filter : configuration.getFilters()) {
			if (!filter.select(item)) {
				return false;
			}
		}

		return true;
	}

	public Catalog getCatalog() {
		return catalog;
	}

	public List<CatalogItem> getCheckedItems() {
		return new ArrayList<CatalogItem>(checkedItems);
	}

	public CatalogConfiguration getConfiguration() {
		return configuration;
	}

	protected Set<String> getInstalledFeatures(IProgressMonitor monitor) {
		Set<String> features = new HashSet<String>();
		IProfile profile = ProvUI.getProfileRegistry(ProvisioningUI.getDefaultUI().getSession()).getProfile(ProvisioningUI.getDefaultUI().getProfileId());
		IQueryResult<IInstallableUnit> result = profile.available(QueryUtil.createIUGroupQuery(), monitor);
		for (Iterator<IInstallableUnit> it = result.iterator(); it.hasNext();) {
			IInstallableUnit unit = it.next();
			features.add(unit.getId());
		}
		return features;
	}

	protected DiscoveryResources getResources() {
		return resources;
	}

	public IStructuredSelection getSelection() {
		return (IStructuredSelection) selectionProvider.getSelection();
	}

	private Shell getShell() {
		return shellProvider.getShell();
	}

	public boolean isComplete() {
		return complete;
	}

	public boolean isShowCategories() {
		return showCategories;
	}

	public boolean isShowInstalled() {
		return showInstalled;
	}

	private boolean isTagVisible(CatalogItem item) {
		if (!configuration.isShowTagFilter()) {
			return true;
		}
		for (Tag selectedTag : visibleTags) {
			for (Tag tag : item.getTags()) {
				if (tag.equals(selectedTag)) {
					return true;
				}
			}
		}
		return false;
	}

	protected void modifySelection(final CatalogItem connector, boolean selected) {
		modifySelectionInternal(connector, selected);
		updateState();
	}

	private void modifySelectionInternal(final CatalogItem connector, boolean selected) {
		connector.setSelected(selected);
		if (selected) {
			checkedItems.add(connector);
		} else {
			checkedItems.remove(connector);
		}
	}

	protected void postDiscovery() {
		for (CatalogItem connector : catalog.getItems()) {
			connector.setInstalled(installedFeatures != null && installedFeatures.containsAll(connector.getInstallableUnits()));
		}
	}

	public void refresh() {
		if (viewer != null && !viewer.getControl().isDisposed()) {
			viewer.refresh();
		}
	}

	public void removeSelectionChangedListener(ISelectionChangedListener listener) {
		selectionProvider.removeSelectionChangedListener(listener);
	}

	public void setComplete(boolean complete) {
		this.complete = complete;
	}

	public void setSelection(IStructuredSelection selection) {
		Set<CatalogItem> selected = new HashSet<CatalogItem>();
		for (Object descriptor : selection.toArray()) {
			if (descriptor instanceof CatalogItem) {
				selected.add((CatalogItem) descriptor);
			}
		}
		for (CatalogItem connector : catalog.getItems()) {
			modifySelectionInternal(connector, selected.contains(connector));
		}
		updateState();
	}

	public void setShowInstalled(boolean showInstalled) {
		this.showInstalled = showInstalled;
		showInstalledCheckbox.setSelection(showInstalled);
		refresh();
	}

	public void setShowCategories(boolean showCategories) {
		this.showCategories = showCategories;
		if (contentProvider != null) {
			contentProvider.setHasCategories(showCategories);
			refresh();
		}
	}

	public void updateCatalog() {
		boolean wasCancelled = false;
		boolean wasError = false;
		try {
			final IStatus[] result = new IStatus[1];
			context.run(true, true, new IRunnableWithProgress() {
				public void run(IProgressMonitor monitor) throws InterruptedException {
					if (installedFeatures == null) {
						installedFeatures = getInstalledFeatures(monitor);
					}

					result[0] = catalog.performDiscovery(monitor);
					if (monitor.isCanceled()) {
						throw new InterruptedException();
					}

					postDiscovery();
				}
			});

			if (result[0] != null && !result[0].isOK()) {
				StatusManager.getManager().handle(result[0], StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
				wasError = true;
			}
		} catch (InvocationTargetException e) {
			IStatus status = computeStatus(e, Messages.ConnectorDiscoveryWizardMainPage_unexpectedException);
			StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
			wasError = true;
		} catch (InterruptedException e) {
			// cancelled by user so nothing to do here.
			wasCancelled = true;
		}
		if (catalog != null) {
			catalogUpdated(wasCancelled, wasError);
			if (configuration.isVerifyUpdateSiteAvailability() && !catalog.getItems().isEmpty()) {
				try {
					context.run(true, true, new IRunnableWithProgress() {
						public void run(IProgressMonitor monitor) {
							//discovery.verifySiteAvailability(monitor);
						}
					});
				} catch (InvocationTargetException e) {
					IStatus status = computeStatus(e, Messages.ConnectorDiscoveryWizardMainPage_unexpectedException);
					StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
					wasError = true;
				} catch (InterruptedException e) {
					// cancelled by user so nothing to do here.
					wasCancelled = true;
				}
			}
		}
		// help UI tests
		viewer.setData("discoveryComplete", "true"); //$NON-NLS-1$//$NON-NLS-2$
	}

	private void updateState() {
		setComplete(!checkedItems.isEmpty());
		selectionProvider.setSelection(new StructuredSelection(getCheckedItems()));
	}

}

Back to the top