blob: bcbc14353b1ef40b05f5a1197ffb8574431a7581 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2005 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jem.internal.beaninfo.ui;
/*
*/
import java.text.MessageFormat;
import java.util.*;
import java.util.List;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.jem.internal.beaninfo.core.BeaninfoEntry;
import org.eclipse.jem.internal.beaninfo.core.SearchpathEntry;
/**
* This dialog is used to display and modify the search path
* within a BeaninfoEntry.
* @version 1.0
* @author
*/
public class BeaninfoEntrySearchpathDialog extends Dialog {
protected BPBeaninfoListElement infoElement;
protected IJavaProject jProject;
//protected ListDialogField listField;
private Composite top;
private Table table;
private TableViewer tableViewer;
private Label label;
private Composite buttonsBar;
private Button upbutton;
private Button downButton;
private Button choosePackagesButton;
private Button removeButton;
private List tableElements;
private boolean enabled = true;
public BeaninfoEntrySearchpathDialog(
Shell parentShell,
BPBeaninfoListElement infoElement,
IJavaProject jProject) {
super(parentShell);
this.infoElement = infoElement;
this.jProject = jProject;
this.tableElements = new ArrayList();
}
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText(
MessageFormat.format(
BeanInfoUIMessages.SearchPathDialog_ModifySearchPaths,
new Object[] { infoElement.getEntry().getPath().toString()}));
}
protected Control createDialogArea(Composite parent) {
top = new Composite(parent, SWT.NONE);
top.setLayoutData(new GridData(GridData.FILL_BOTH));
top.setLayout(new GridLayout(2, false));
label = new Label(top, SWT.NONE);
label.setText(BeanInfoUIMessages.SearchPathDialog_Desc_Label);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
label.setLayoutData(gd);
createTable();
createButtonsBar();
updatePackagesList();
updateButtons();
return top;
}
/**
* This method initializes table
*
*/
private void createTable() {
GridData gridData1 = new org.eclipse.swt.layout.GridData();
gridData1.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
gridData1.grabExcessHorizontalSpace = true;
gridData1.grabExcessVerticalSpace = true;
gridData1.verticalAlignment = org.eclipse.swt.layout.GridData.FILL;
table = new Table(top, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
table.setLayoutData(gridData1);
table.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
updateButtons();
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
});
tableViewer = new TableViewer(table);
//tableViewer.setSorter(new BIListElementSorter());
tableViewer.setContentProvider(new ArrayContentProvider());
tableViewer.setLabelProvider(new SearchPathListLabelProvider(jProject));
tableViewer.setInput(tableElements);
}
/**
* This method initializes buttonsBar
*
*/
private void createButtonsBar() {
RowLayout rowLayout = new RowLayout();
rowLayout.type = org.eclipse.swt.SWT.VERTICAL;
rowLayout.marginLeft = 3;
rowLayout.fill = true;
GridData gridData2 = new org.eclipse.swt.layout.GridData();
gridData2.grabExcessVerticalSpace = true;
gridData2.verticalAlignment = org.eclipse.swt.layout.GridData.FILL;
gridData2.horizontalAlignment = org.eclipse.swt.layout.GridData.BEGINNING;
buttonsBar = new Composite(top, SWT.NONE);
buttonsBar.setLayoutData(gridData2);
buttonsBar.setLayout(rowLayout);
upbutton = new Button(buttonsBar, SWT.NONE);
upbutton.setText(BeanInfoUIMessages.BeaninfoPathsBlock_UI__searchpath_up_button);
upbutton.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
List selected = BeaninfoPathsBlock.getSelectedList(tableViewer.getSelection());
Iterator selItr = selected.iterator();
while (selItr.hasNext()) {
Object element = selItr.next();
int oldIndex = tableElements.indexOf(element);
if(oldIndex>0){
tableElements.remove(element);
tableElements.add(--oldIndex, element);
}
}
tableViewer.refresh();
pageChanged();
}
});
downButton = new Button(buttonsBar, SWT.NONE);
downButton.setText(BeanInfoUIMessages.BeaninfoPathsBlock_UI__searchpath_down_button);
downButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
List selected = BeaninfoPathsBlock.getSelectedList(tableViewer.getSelection());
Iterator selItr = selected.iterator();
while (selItr.hasNext()) {
Object element = selItr.next();
int oldIndex = tableElements.indexOf(element);
if(oldIndex<(tableElements.size()-1)){
tableElements.remove(element);
tableElements.add(++oldIndex, element);
}
}
tableViewer.refresh();
pageChanged();
}
});
new Label(buttonsBar, SWT.NONE);
choosePackagesButton = new Button(buttonsBar, SWT.NONE);
choosePackagesButton.setText(BeanInfoUIMessages.SearchPathDialog_ChoosePackages);
choosePackagesButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
final List elementsToAdd = choosePackages();
if (elementsToAdd != null && !elementsToAdd.isEmpty()) {
tableElements.addAll(elementsToAdd);
tableViewer.refresh();
table.getDisplay().asyncExec(new Runnable(){
public void run() {
tableViewer.setSelection(new StructuredSelection(elementsToAdd));
};
});
}
}
});
new Label(buttonsBar, SWT.NONE);
removeButton = new Button(buttonsBar, SWT.NONE);
removeButton.setText(BeanInfoUIMessages.SearchPathDialog_Remove);
removeButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
List selected = BeaninfoPathsBlock.getSelectedList(tableViewer.getSelection());
tableElements.removeAll(selected);
tableViewer.refresh();
pageChanged();
}
});
}
protected void pageChanged() {
// TODO Auto-generated method stub
}
protected void updateButtons() {
if(top!=null && !top.isDisposed()){
upbutton.setEnabled(enabled && canMoveUp());
downButton.setEnabled(enabled && canMoveDown());
removeButton.setEnabled(enabled && !tableViewer.getSelection().isEmpty());
choosePackagesButton.setEnabled(enabled);
}
}
private boolean canMoveDown() {
int[] indc= table.getSelectionIndices();
int k= tableElements.size() - 1;
for (int i= indc.length - 1; i >= 0 ; i--, k--) {
if (indc[i] != k) {
return true;
}
}
return false;
}
private boolean canMoveUp() {
int[] indc= table.getSelectionIndices();
for (int i= 0; i < indc.length; i++) {
if (indc[i] != i) {
return true;
}
}
return false;
}
private void updatePackagesList() {
if (infoElement.getEntry().getKind() == BeaninfoEntry.BIE_PLUGIN) {
// We don't allow these to be updated. They should only be used through
// registered mechanisms and we won't be showing them here normally.
label.setText(BeanInfoUIMessages.SearchPathDialog_NotEditable_INFO_);
updateEnabledState(false);
return;
}
tableElements.clear();
tableElements.addAll(Arrays.asList(infoElement.getSearchpaths()));
tableViewer.refresh();
}
private void updateEnabledState(boolean b) {
enabled = b;
if(top!=null && !top.isDisposed()){
label.setEnabled(enabled);
table.setEnabled(enabled);
updateButtons();
}
}
protected void okPressed() {
if (table.isEnabled()) {
// If the field is not enabled, then there is no update to perform. We don't
// want to accidentially wipe out the search paths in this case.
// Override to put the list of elements back into the BPBeaninfoListElement
// Until then they aren't actually updated.
infoElement.setSearchpaths(
(BPSearchListElement[]) tableElements.toArray(new BPSearchListElement[tableElements.size()]));
}
super.okPressed();
}
/**
* Choose the packages that should be in the search path.
*/
private List choosePackages() {
IPackageFragmentRoot[] roots = getBeaninfoRoots();
List newPackageNames = new ArrayList();
if (roots != null) {
// It's within the workspace, so we can get the roots and packages.
ISelectionStatusValidator validator = new PackagesWorkbookPage.ChoosePackagesSelectionValidator();
// Show up to the package fragment, don't show any contents of it.
Class[] acceptedClasses = new Class[] { IPackageFragmentRoot.class, IPackageFragment.class };
Object[] rejectedFragments = getFilteredExistingEntries(roots);
// Only show package fragments that have children (i.e. there classes in it, not interested
// in intermediate ones that have no classes defined in them. Those are filtered out.
TypedViewerFilter filter = new TypedViewerFilter(acceptedClasses, rejectedFragments) {
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (super.select(viewer, parentElement, element)) {
if (element instanceof IPackageFragment) {
IPackageFragment pkg = (IPackageFragment) element;
try {
return pkg.hasChildren();
} catch (JavaModelException e) {
}
return false;
} else
return true;
}
return false;
}
};
ITreeContentProvider provider = new PackageOnlyContentProvider();
ILabelProvider labelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
ElementTreeSelectionDialog dialog =
new ElementTreeSelectionDialog(getShell(), labelProvider, provider);
dialog.setTitle(BeanInfoUIMessages.BeaninfoPathsBlock_UI__addsearchpath_title);
dialog.setValidator(validator);
dialog.setMessage(BeanInfoUIMessages.BeaninfoPathsBlock_UI__addsearchpath_description);
dialog.addFilter(filter);
dialog.setInput(Arrays.asList(getBeaninfoRoots()));
if (dialog.open() == Window.OK) {
Object[] elements = dialog.getResult();
for (int i = 0; i < elements.length; i++) {
newPackageNames.add(((IPackageFragment) elements[i]).getElementName());
}
}
} else {
// It's not within the workspace
final List existingPackagenames = getFilteredExistingEntries();
IInputValidator validator = new IInputValidator() {
public String isValid(String newText) {
if (existingPackagenames.contains(newText))
return BeanInfoUIMessages.SearchPathDialog_PackagePresent_INFO_;
IStatus status = JavaConventions.validatePackageName(newText);
return status.getSeverity() == IStatus.OK ? null : status.getMessage();
}
};
InputDialog dialog = new InputDialog(getShell(), BeanInfoUIMessages.SearchPathDialog_InputDialog_Title, BeanInfoUIMessages.SearchPathDialog_InputDialog_Message, null, validator);
if (dialog.open() == Window.OK)
newPackageNames.add(dialog.getValue());
}
if (newPackageNames.size() == 0)
return Collections.EMPTY_LIST;
List newElements = new ArrayList(newPackageNames.size());
for (int i = 0; i < newPackageNames.size(); i++)
newElements.add(
new BPSearchListElement(new SearchpathEntry((String) newPackageNames.get(i)), false, false, false));
return newElements;
}
/**
* Return the packagefragment roots for the given beaninfo entry.
* Return null if it can be handled (i.e. not in a project some where).
*/
protected IPackageFragmentRoot[] getBeaninfoRoots() {
IPackageFragmentRoot[] roots = null;
if (infoElement.getEntry().getKind() != BeaninfoEntry.BIE_PLUGIN) {
IClasspathEntry resolved = JavaCore.getResolvedClasspathEntry(((BeaninfoEntry) infoElement.getEntry()).getClasspathEntry());
IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(resolved.getPath());
if (res != null && res.exists()) {
if (res instanceof IProject) {
// It is a project itself.
IJavaProject jp = (IJavaProject) JavaCore.create(res);
try {
if (jp != null)
roots = jp.getPackageFragmentRoots(); // All of the roots in the project are applicable.
} catch (JavaModelException e) {
}
} else {
// It is within another project
IProject containingProject = res.getProject();
IJavaProject jp = JavaCore.create(containingProject);
if (jp != null) {
// The roots if this is in the classpath of this project
try {
IPackageFragmentRoot root = jp.findPackageFragmentRoot(resolved.getPath());
if (root != null)
roots = new IPackageFragmentRoot[] { root };
} catch (JavaModelException e) {
}
}
}
}
}
return roots;
}
/**
* Return the list of entries that already are in the search path
* so that they don't show up in the list.
*/
protected Object[] getFilteredExistingEntries(IPackageFragmentRoot[] roots) {
List entries = tableElements;
List fragments = new ArrayList(entries.size());
Iterator itr = entries.iterator();
while (itr.hasNext()) {
BPSearchListElement elem = (BPSearchListElement) itr.next();
fragments.addAll(getPackages(elem, roots));
}
return fragments.toArray();
}
/**
* Return the list of entries that already are in the search path
* so that they don't show up in the list. This one is just the package names.
*/
protected List getFilteredExistingEntries() {
List entries = tableElements;
List names = new ArrayList(entries.size());
Iterator itr = entries.iterator();
while (itr.hasNext()) {
BPSearchListElement elem = (BPSearchListElement) itr.next();
names.add(((SearchpathEntry) elem.getEntry()).getPackage());
}
return names;
}
protected List getPackages(BPSearchListElement element, IPackageFragmentRoot[] roots) {
String packageName = ((SearchpathEntry) element.getEntry()).getPackage();
if (packageName == null)
return Collections.EMPTY_LIST;
try {
List packages = new ArrayList(10);
for (int i = 0; i < roots.length; i++) {
IJavaElement[] pfs = roots[i].getChildren();
for (int j = 0; j < pfs.length; j++)
if (pfs[j].getElementType() == IJavaElement.PACKAGE_FRAGMENT
&& pfs[j].getElementName().equals(packageName)) {
packages.add(pfs[j]);
break;
}
}
return packages;
} catch (JavaModelException e) {
}
return Collections.EMPTY_LIST;
}
}