package bndtools.wizards.project; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Text; import aQute.bnd.osgi.Jar; import aQute.bnd.osgi.Resource; import bndtools.internal.pkgselection.PackageNameLabelProvider; public class PackageListWizardPage extends WizardPage { private boolean loaded = false; private boolean programmaticChange = false; private boolean uiChange = false; private Collection<IPath> paths; private final PropertyChangeSupport propSupport = new PropertyChangeSupport(this); private final List<IPath> availablePackages = new ArrayList<IPath>(); private final List<IPath> selectedPackages = new ArrayList<IPath>(); private String projectName = null; private Table tblAvailable; private TableViewer selectedViewer; private Table tblSelected; private TableViewer availableViewer; private Button btnAdd; private Button btnAddAll; private Button btnRemove; private Button btnRemoveAll; private Text txtProjectName; protected PackageListWizardPage(String pageName) { super(pageName); setTitle("Select Packages"); setMessage("The selected packages will be included in the bundle and provided as Exports."); } @SuppressWarnings("unused") public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); setControl(composite); composite.setLayout(new GridLayout(3, false)); Label lblAvailablePackages = new Label(composite, SWT.NONE); lblAvailablePackages.setText("Available Packages:"); new Label(composite, SWT.NONE); Label lblSelectedPackages = new Label(composite, SWT.NONE); lblSelectedPackages.setText("Selected Packages:"); tblAvailable = new Table(composite, SWT.BORDER | SWT.FULL_SELECTION); tblAvailable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); availableViewer = new TableViewer(tblAvailable); availableViewer.setContentProvider(ArrayContentProvider.getInstance()); availableViewer.setLabelProvider(new PackageNameLabelProvider()); availableViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updateUI(); } }); availableViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { doAddSelection(); } }); Composite composite_1 = new Composite(composite, SWT.NONE); GridLayout gl_composite_1 = new GridLayout(1, false); gl_composite_1.marginWidth = 0; gl_composite_1.marginHeight = 0; composite_1.setLayout(gl_composite_1); btnAdd = new Button(composite_1, SWT.NONE); btnAdd.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); btnAdd.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { doAddSelection(); } }); btnAdd.setText("Add ->"); btnAdd.setEnabled(false); btnAddAll = new Button(composite_1, SWT.NONE); btnAddAll.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); btnAddAll.setText("Add All ->"); btnAddAll.setEnabled(false); btnAddAll.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { doAddAll(); } }); btnRemove = new Button(composite_1, SWT.NONE); btnRemove.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); btnRemove.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { doRemoveSelection(); } }); btnRemove.setText("<- Remove"); btnRemove.setEnabled(false); btnRemoveAll = new Button(composite_1, SWT.NONE); btnRemoveAll.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); btnRemoveAll.setText("<- Remove All"); btnRemoveAll.setEnabled(false); btnRemoveAll.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { doRemoveAll(); } }); tblSelected = new Table(composite, SWT.BORDER | SWT.FULL_SELECTION); tblSelected.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); selectedViewer = new TableViewer(tblSelected); selectedViewer.setContentProvider(ArrayContentProvider.getInstance()); selectedViewer.setLabelProvider(new PackageNameLabelProvider()); selectedViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updateUI(); } }); selectedViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { doRemoveSelection(); } }); Composite composite_2 = new Composite(composite, SWT.NONE); composite_2.setLayout(new GridLayout(2, false)); composite_2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); Label lblNewLabel = new Label(composite_2, SWT.NONE); lblNewLabel.setText("Project Name:"); txtProjectName = new Text(composite_2, SWT.BORDER); txtProjectName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); txtProjectName.setText(projectName != null ? projectName : ""); txtProjectName.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { if (!programmaticChange) { try { uiChange = true; setProjectName(txtProjectName.getText()); } finally { uiChange = false; } } } }); } void setJarPaths(Collection<IPath> paths) { loaded = false; this.paths = paths; } @Override public void setVisible(boolean visible) { super.setVisible(visible); if (!loaded) { try { getContainer().run(false, false, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { availablePackages.clear(); selectedPackages.clear(); for (IPath path : paths) { Jar jar = null; try { if (path.isAbsolute()) jar = new Jar(path.toFile()); else jar = new Jar(ResourcesPlugin.getWorkspace().getRoot().getLocation().append(path).toFile()); Map<String,Map<String,Resource>> dirs = jar.getDirectories(); for (Entry<String,Map<String,Resource>> entry : dirs.entrySet()) { if (entry.getValue() == null) continue; IPath packagePath = new Path(entry.getKey()); if (packagePath.segmentCount() < 1) continue; if ("META-INF".equalsIgnoreCase(packagePath.segment(0))) continue; availablePackages.add(packagePath); } } catch (Exception e) {} finally { if (jar != null) jar.close(); } } } }); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { loaded = true; } availableViewer.setInput(availablePackages); selectedViewer.setInput(selectedPackages); } updateUI(); } private void updateUI() { btnAdd.setEnabled(!availableViewer.getSelection().isEmpty()); btnAddAll.setEnabled(!availablePackages.isEmpty()); btnRemove.setEnabled(!selectedViewer.getSelection().isEmpty()); btnRemoveAll.setEnabled(!selectedPackages.isEmpty()); getContainer().updateButtons(); getContainer().updateMessage(); } @Override public boolean isPageComplete() { return !selectedPackages.isEmpty() && projectName != null && projectName.length() > 0; } private String getWarning() { String warning = null; if (projectName == null || projectName.length() == 0) warning = "Project name must be specified."; return warning; } @Override public String getMessage() { String message = getWarning(); if (message == null) message = "The selected packages will be included in the generated bundle, and exported as API packages."; return message; } @Override public int getMessageType() { return getWarning() != null ? IMessageProvider.WARNING : IMessageProvider.NONE; } public String getProjectName() { return projectName; } public void setProjectName(String name) { try { programmaticChange = true; String oldName = this.projectName; this.projectName = name; if (txtProjectName != null && !txtProjectName.isDisposed()) { if (!uiChange) txtProjectName.setText(projectName); updateUI(); } propSupport.firePropertyChange("projectName", oldName, name); } finally { programmaticChange = false; } } public List<IPath> getSelectedPackages() { return selectedPackages; } public void addPropertyChangeListener(PropertyChangeListener listener) { propSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { propSupport.removePropertyChangeListener(listener); } public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { propSupport.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { propSupport.removePropertyChangeListener(propertyName, listener); } @SuppressWarnings("unchecked") void doAddSelection() { IStructuredSelection sel = (IStructuredSelection) availableViewer.getSelection(); availablePackages.removeAll(sel.toList()); availableViewer.remove(sel.toArray()); selectedPackages.addAll(sel.toList()); selectedViewer.add(sel.toArray()); updateUI(); } void doAddAll() { selectedPackages.addAll(availablePackages); selectedViewer.add(availablePackages.toArray()); availablePackages.clear(); availableViewer.refresh(); updateUI(); } @SuppressWarnings("unchecked") void doRemoveSelection() { IStructuredSelection sel = (IStructuredSelection) selectedViewer.getSelection(); selectedPackages.removeAll(sel.toList()); selectedViewer.remove(sel.toArray()); availablePackages.addAll(sel.toList()); availableViewer.add(sel.toArray()); updateUI(); } void doRemoveAll() { availablePackages.addAll(selectedPackages); availableViewer.add(selectedPackages.toArray()); selectedPackages.clear(); selectedViewer.refresh(); updateUI(); } }