/******************************************************************************* * Copyright (c) 2010 BestSolution.at 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: * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation ******************************************************************************/ package at.bestsolution.efxclipse.tooling.ui.wizards; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import org.eclipse.core.databinding.Binding; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.UpdateValueStrategy; import org.eclipse.core.databinding.beans.BeanProperties; import org.eclipse.core.databinding.conversion.Converter; import org.eclipse.core.databinding.validation.IValidator; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaModel; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator; import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter; import org.eclipse.jdt.ui.JavaElementComparator; import org.eclipse.jdt.ui.JavaElementLabelProvider; import org.eclipse.jdt.ui.StandardJavaElementContentProvider; import org.eclipse.jface.databinding.swt.IWidgetValueProperty; import org.eclipse.jface.databinding.swt.WidgetProperties; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; 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.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.ElementListSelectionDialog; import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; import at.bestsolution.efxclipse.tooling.ui.wizards.template.JDTElement; @SuppressWarnings("restriction") public abstract class AbstractJDTElementPage<O extends JDTElement> extends WizardPage { private O clazz; private IPackageFragmentRoot froot; private IPackageFragment fragment; private IWorkspaceRoot fWorkspaceRoot; private Text nameField; protected AbstractJDTElementPage(String pageName, String title, String description, IPackageFragmentRoot froot, IPackageFragment fragment, IWorkspaceRoot fWorkspaceRoot) { super(pageName); this.froot = froot; this.fragment = fragment; this.fWorkspaceRoot = fWorkspaceRoot; setTitle(title); setDescription(description); setImageDescriptor(getTitleAreaImage(Display.getCurrent())); } public void createControl(Composite parent) { parent = new Composite(parent, SWT.NULL); parent.setLayoutData(new GridData(GridData.FILL_BOTH)); parent.setLayout(new GridLayout(3, false)); clazz = createInstance(); clazz.setFragmentRoot(froot); clazz.setPackageFragment(fragment); DataBindingContext dbc = new DataBindingContext(); { Label l = new Label(parent, SWT.NONE); l.setText("Source folder"); Text t = new Text(parent, SWT.BORDER); t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); t.setEditable(false); final Binding bd = dbc.bindValue( WidgetProperties.text().observe(t), BeanProperties.value("fragmentRoot").observe(clazz), new UpdateValueStrategy(), new UpdateValueStrategy().setConverter(new PackageFragmentRootToStringConverter()) ); Button b = new Button(parent, SWT.PUSH); b.setText("Browse ..."); b.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IPackageFragmentRoot root = choosePackageRoot(); if( root != null ) { froot = root; clazz.setFragmentRoot(root); } bd.updateModelToTarget(); //TODO Find out why this is needed } }); } { Label l = new Label(parent, SWT.NONE); l.setText("Package"); Text t = new Text(parent, SWT.BORDER); t.setEditable(false); t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); final Binding bd = dbc.bindValue( WidgetProperties.text().observe(t), BeanProperties.value("packageFragment").observe(clazz), new UpdateValueStrategy(), new UpdateValueStrategy().setConverter(new PackageFragmentToStringConverter()) ); Button b = new Button(parent, SWT.PUSH); b.setText("Browse ..."); b.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IPackageFragment fragment = choosePackage(); if( fragment != null ) { clazz.setPackageFragment(fragment); } bd.updateModelToTarget(); //TODO Find out why this is needed } }); } { IWidgetValueProperty textProp = WidgetProperties.text(SWT.Modify); Label l = new Label(parent, SWT.NONE); l.setText("Name"); nameField = new Text(parent, SWT.BORDER); nameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); dbc.bindValue(textProp.observe(nameField), BeanProperties.value("name", String.class).observe(clazz)); new Label(parent, SWT.NONE); } { Label l = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); l.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, 3, 1)); } createFields(parent, dbc); setControl(parent); clazz.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { revalidate(); } }); setPageComplete(false); } @Override public void setVisible(boolean visible) { super.setVisible(visible); if( visible ) { nameField.setFocus(); } } protected void revalidate() { if( getClazz().getName() == null || getClazz().getName().trim().length() == 0 ) { setPageComplete(false); setMessage("Enter a name", IMessageProvider.ERROR); } else { setPageComplete(true); setMessage(null); } } private IPackageFragmentRoot choosePackageRoot() { IJavaElement initElement= clazz.getFragmentRoot(); Class<?>[] acceptedClasses= new Class<?>[] { IPackageFragmentRoot.class, IJavaProject.class }; TypedElementSelectionValidator validator= new TypedElementSelectionValidator(acceptedClasses, false) { public boolean isSelectedValid(Object element) { try { if (element instanceof IJavaProject) { IJavaProject jproject= (IJavaProject)element; IPath path= jproject.getProject().getFullPath(); return (jproject.findPackageFragmentRoot(path) != null); } else if (element instanceof IPackageFragmentRoot) { return (((IPackageFragmentRoot)element).getKind() == IPackageFragmentRoot.K_SOURCE); } return true; } catch (JavaModelException e) { JavaPlugin.log(e.getStatus()); // just log, no UI in validation } return false; } }; acceptedClasses= new Class[] { IJavaModel.class, IPackageFragmentRoot.class, IJavaProject.class }; ViewerFilter filter= new TypedViewerFilter(acceptedClasses) { public boolean select(Viewer viewer, Object parent, Object element) { if (element instanceof IPackageFragmentRoot) { try { return (((IPackageFragmentRoot)element).getKind() == IPackageFragmentRoot.K_SOURCE); } catch (JavaModelException e) { JavaPlugin.log(e.getStatus()); // just log, no UI in validation return false; } } return super.select(viewer, parent, element); } }; StandardJavaElementContentProvider provider= new StandardJavaElementContentProvider(); ILabelProvider labelProvider= new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT); ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getShell(), labelProvider, provider); dialog.setValidator(validator); dialog.setComparator(new JavaElementComparator()); dialog.setTitle(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_title); dialog.setMessage(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_description); dialog.addFilter(filter); dialog.setInput(JavaCore.create(fWorkspaceRoot)); dialog.setInitialSelection(initElement); dialog.setHelpAvailable(false); if (dialog.open() == Window.OK) { Object element= dialog.getFirstResult(); if (element instanceof IJavaProject) { IJavaProject jproject= (IJavaProject)element; return jproject.getPackageFragmentRoot(jproject.getProject()); } else if (element instanceof IPackageFragmentRoot) { return (IPackageFragmentRoot)element; } return null; } return null; } private IPackageFragment choosePackage() { IJavaElement[] packages= null; try { if (froot != null && froot.exists()) { packages= froot.getChildren(); } } catch (JavaModelException e) { e.printStackTrace(); } if (packages == null) { packages= new IJavaElement[0]; } ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT)); dialog.setIgnoreCase(false); dialog.setTitle("Choose Package"); dialog.setMessage("Choose a Package"); dialog.setEmptyListMessage("You need to select a package"); dialog.setElements(packages); dialog.setHelpAvailable(false); IPackageFragment pack= clazz.getPackageFragment(); if (pack != null) { dialog.setInitialSelections(new Object[] { pack }); } if (dialog.open() == Window.OK) { return (IPackageFragment) dialog.getFirstResult(); } return null; } protected IPackageFragmentRoot getFragmentRoot() { return froot; } protected abstract void createFields(Composite parent, DataBindingContext dbc); protected abstract O createInstance(); protected abstract ImageDescriptor getTitleAreaImage(Display display); public O getClazz() { return clazz; } static class ClassnameValidator implements IValidator { public IStatus validate(Object value) { String name = value.toString(); char[] ar = name.toCharArray(); for (char c : ar) { if (!Character.isJavaIdentifierPart(c)) { return new Status(IStatus.ERROR, "", "'" + c + "' is not allowed in a Class-Name"); } } if (!Character.isJavaIdentifierStart(ar[0])) { return new Status(IStatus.ERROR, "", "'" + ar[0] + "' is not allowed as the first character of a Class-Name"); } return Status.OK_STATUS; } } static class PackageFragmentRootToStringConverter extends Converter { public PackageFragmentRootToStringConverter() { super(IPackageFragmentRoot.class, String.class); } public Object convert(Object fromObject) { IPackageFragmentRoot f = (IPackageFragmentRoot) fromObject; if( f == null ) { return ""; } return f.getPath().makeRelative().toString(); } } static class PackageFragmentToStringConverter extends Converter { public PackageFragmentToStringConverter() { super(IPackageFragment.class, String.class); } public Object convert(Object fromObject) { if( fromObject == null ) { return ""; } IPackageFragment f = (IPackageFragment) fromObject; return f.getElementName(); } } }