Java tutorial
/******************************************************************************* * Copyright (c) 2011 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.openshift.express.internal.ui.wizard.application; import java.util.ArrayList; import java.util.List; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.beans.BeanProperties; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.validation.MultiValidator; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.databinding.fieldassist.ControlDecorationSupport; import org.eclipse.jface.databinding.swt.ISWTObservableValue; import org.eclipse.jface.databinding.swt.WidgetProperties; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.PageChangingEvent; import org.eclipse.jface.fieldassist.AutoCompleteField; import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.jface.fieldassist.FieldDecoration; import org.eclipse.jface.fieldassist.FieldDecorationRegistry; import org.eclipse.jface.fieldassist.TextContentAdapter; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.wizard.IWizard; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.WorkingSetGroup; import org.jboss.tools.common.ui.databinding.InvertingBooleanConverter; import org.jboss.tools.common.ui.databinding.ValueBindingBuilder; import org.jboss.tools.openshift.express.internal.ui.OpenShiftUIActivator; import org.jboss.tools.openshift.express.internal.ui.utils.StringUtils; import org.jboss.tools.openshift.express.internal.ui.wizard.AbstractOpenShiftWizardPage; /** * @author Andre Dietisheim * @author Xavier Coulon */ public class ProjectAndServerAdapterSettingsWizardPage extends AbstractOpenShiftWizardPage { public static final String PREF_CONTENTASSISTKEY = "prefContentAssistKey"; private static final String PAGE_TITLE_FORMAT = "Setup Project for OpenShift Application \"{0}\""; private ProjectAndServerAdapterSettingsWizardPageModel pageModel; private Text existingProjectNameText = null; public ProjectAndServerAdapterSettingsWizardPage(IWizard wizard, IOpenShiftExpressWizardModel wizardModel) { super(NLS.bind(PAGE_TITLE_FORMAT, wizardModel.getApplicationName()), "Configure your project and server adapter settings, then click 'next' or 'finish'.", "Project Configuration", wizard); this.pageModel = new ProjectAndServerAdapterSettingsWizardPageModel(wizardModel); } @Override protected void doCreateControls(Composite container, DataBindingContext dbc) { GridLayoutFactory.fillDefaults().numColumns(1).applyTo(container); createProjectGroup(container, dbc); createServerAdapterGroup(container, dbc); // createWorkingSetGroup(container, dbc); } private Composite createProjectGroup(Composite parent, DataBindingContext dbc) { Composite projectGroup = new Composite(parent, SWT.NONE); // projectGroup.setText("Project"); GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).align(SWT.FILL, SWT.CENTER).grab(true, false) .applyTo(projectGroup); GridLayoutFactory.fillDefaults().numColumns(3).margins(6, 6).applyTo(projectGroup); // new project checkbox Button newProjectRadioBtn = new Button(projectGroup, SWT.CHECK); newProjectRadioBtn.setText("Create a new project"); newProjectRadioBtn.setToolTipText( "The OpenShift application code will be pulled into the newly created project or merged into the selected one."); newProjectRadioBtn.setFocus(); GridDataFactory.fillDefaults().span(3, 1).align(SWT.FILL, SWT.CENTER).grab(false, false) .applyTo(newProjectRadioBtn); final IObservableValue newProjectObservable = BeanProperties .value(ProjectAndServerAdapterSettingsWizardPageModel.PROPERTY_IS_NEW_PROJECT).observe(pageModel); final ISWTObservableValue newProjectRadioBtnSelection = WidgetProperties.selection() .observe(newProjectRadioBtn); dbc.bindValue(newProjectRadioBtnSelection, newProjectObservable); // existing project Label existingProjectLabel = new Label(projectGroup, SWT.NONE); existingProjectLabel.setText("Use existing project:"); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(1, 1).grab(false, false).indent(10, 0) .applyTo(existingProjectLabel); existingProjectNameText = new Text(projectGroup, SWT.BORDER); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(1, 1).grab(true, false) .applyTo(existingProjectNameText); final IObservableValue projectNameModelObservable = BeanProperties .value(ProjectAndServerAdapterSettingsWizardPageModel.PROPERTY_PROJECT_NAME).observe(pageModel); final ISWTObservableValue existingProjectNameTextObservable = WidgetProperties.text(SWT.Modify) .observe(existingProjectNameText); ValueBindingBuilder.bind(existingProjectNameTextObservable).to(projectNameModelObservable).in(dbc); // disable the project name text when the model state is set to 'new project' ValueBindingBuilder.bind(WidgetProperties.enabled().observe(existingProjectNameText)) .notUpdating(newProjectObservable).converting(new InvertingBooleanConverter()).in(dbc); // move focus to the project name text control when choosing the 'Use an existing project' option. newProjectRadioBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { existingProjectNameText.setFocus(); existingProjectNameText.selectAll(); } }); // let's provide content assist on the existing project name ControlDecoration dec = new ControlDecoration(existingProjectNameText, SWT.TOP | SWT.LEFT); FieldDecoration contentProposalFieldIndicator = FieldDecorationRegistry.getDefault() .getFieldDecoration(FieldDecorationRegistry.DEC_CONTENT_PROPOSAL); dec.setImage(contentProposalFieldIndicator.getImage()); dec.setDescriptionText("Auto-completion is enabled when you start typing a project name."); dec.setShowOnlyOnFocus(true); AutoCompleteField adapter = new AutoCompleteField(existingProjectNameText, new TextContentAdapter(), new String[] {}); adapter.setProposals(getOpenProjectsInWorkspace()); Button browseProjectsButton = new Button(projectGroup, SWT.NONE); browseProjectsButton.setText("Browse..."); GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).hint(100, SWT.DEFAULT).span(1, 1) .grab(false, false).applyTo(browseProjectsButton); browseProjectsButton.addSelectionListener(onBrowseProjects()); ValueBindingBuilder.bind(WidgetProperties.enabled().observe(browseProjectsButton)) .notUpdating(newProjectObservable).converting(new InvertingBooleanConverter()).in(dbc); final IObservableValue applicationNameModelObservable = BeanProperties .value(GitCloningSettingsWizardPageModel.PROPERTY_APPLICATION_NAME).observe(pageModel); final UseExistingOpenProjectValidator existingProjectValidator = new UseExistingOpenProjectValidator( applicationNameModelObservable, newProjectObservable, projectNameModelObservable); dbc.addValidationStatusProvider(existingProjectValidator); ControlDecorationSupport.create(existingProjectValidator, SWT.LEFT | SWT.TOP); return projectGroup; } private String[] getOpenProjectsInWorkspace() { List<String> projects = new ArrayList<String>(); for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) { if (project.exists() && project.isOpen()) { projects.add(project.getName()); } } return projects.toArray(new String[projects.size()]); } /** * Open a dialog box to select an open project when clicking on the 'Browse' button. * * @return */ private SelectionListener onBrowseProjects() { return new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { SelectExistingProjectDialog dialog = new SelectExistingProjectDialog(pageModel.getApplicationName(), getShell()); if (dialog.open() == Dialog.OK) { Object selectedProject = dialog.getFirstResult(); if (selectedProject instanceof IProject) { pageModel.setProjectName(((IProject) selectedProject).getName()); } } } }; } private Group createServerAdapterGroup(Composite container, DataBindingContext dbc) { Group serverAdapterGroup = new Group(container, SWT.NONE); serverAdapterGroup.setText("Server Adapter"); GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).align(SWT.FILL, SWT.CENTER).grab(true, false) .applyTo(serverAdapterGroup); GridLayoutFactory.fillDefaults().margins(10, 10).applyTo(serverAdapterGroup); Composite c = new Composite(serverAdapterGroup, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(c); GridLayoutFactory.fillDefaults().numColumns(3).spacing(12, 8).applyTo(c); final Button serverAdapterCheckbox = new Button(c, SWT.CHECK); serverAdapterCheckbox.setText("Create and setup a server for easy publishing"); serverAdapterCheckbox.setToolTipText( "This Server Adapter will let you publish your local changes onto OpenShift, right from your Eclipse workbench."); GridDataFactory.fillDefaults().span(3, 1).align(SWT.FILL, SWT.CENTER).grab(true, false) .applyTo(serverAdapterCheckbox); final IObservableValue serverAdapterCheckboxObservable = WidgetProperties.selection() .observe(serverAdapterCheckbox); final IObservableValue serverAdapterModelObservable = BeanProperties .value(ProjectAndServerAdapterSettingsWizardPageModel.PROPERTY_CREATE_SERVER_ADAPTER) .observe(pageModel); ValueBindingBuilder.bind(serverAdapterCheckboxObservable).to(serverAdapterModelObservable).in(dbc); return serverAdapterGroup; } private WorkingSetGroup createWorkingSetGroup(Composite container, DataBindingContext dbc) { return new WorkingSetGroup(container, null, new String[] { "org.eclipse.ui.resourceWorkingSetPage", //$NON-NLS-1$ "org.eclipse.jdt.ui.JavaWorkingSetPage" /* JavaWorkingSetUpdater.ID */ }); } /** * Verify that if the 'use an existing project' option was chose, then the project name actually matches an open * project in the workspace. */ // @Override // protected void onPageWillGetDeactivated(Direction direction, PageChangingEvent event, DataBindingContext dbc) { // if (direction == Direction.BACKWARDS) { // return; // } // if (!pageModel.isNewProject()) { // try { // final ArrayBlockingQueue<IStatus> queue = new ArrayBlockingQueue<IStatus>(1); // WizardUtils.runInWizard(new Job("Verifying existing project exists and is open...") { // @Override // protected IStatus run(IProgressMonitor monitor) { // IStatus status = pageModel.validateExistingProject(); // queue.offer(status); // monitor.done(); // return Status.OK_STATUS; // } // }, new DelegatingProgressMonitor(), getContainer(), getDatabindingContext()); // final IStatus status = queue.poll(10, TimeUnit.SECONDS); // event.doit = status.isOK(); // if (!event.doit) { // existingProjectNameText.setFocus(); // existingProjectNameText.selectAll(); // } // } catch (Exception ex) { // event.doit = false; // } finally { // } // // } // } class UseExistingOpenProjectValidator extends MultiValidator { private final IObservableValue applicationNameObservable; private final IObservableValue newProjectObservable; private final IObservableValue projectNameObservable; public UseExistingOpenProjectValidator(IObservableValue applicationNameObservable, IObservableValue newProjectObservable, IObservableValue projectNameObservable) { this.applicationNameObservable = applicationNameObservable; this.newProjectObservable = newProjectObservable; this.projectNameObservable = projectNameObservable; } @Override public IStatus validate() { IStatus status = Status.OK_STATUS; final String projectName = (String) projectNameObservable.getValue(); final Boolean isNewProject = (Boolean) newProjectObservable.getValue(); if (isNewProject) { final String applicationName = (String) applicationNameObservable.getValue(); if (StringUtils.isEmptyOrNull(applicationName)) { status = OpenShiftUIActivator.createErrorStatus("You have to choose an application name"); } else if (!StringUtils.isAlphaNumeric(applicationName)) { status = OpenShiftUIActivator .createErrorStatus("The name may only contain lower-case letters and digits."); } else { final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(applicationName); if (project.exists()) { status = OpenShiftUIActivator.createErrorStatus( NLS.bind("A project named {0} already exists in the workspace.", applicationName)); } } } else { if (projectName == null || projectName.isEmpty()) { status = OpenShiftUIActivator.createErrorStatus("Select an open project in the workspace."); } else { final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); if (!project.exists()) { status = OpenShiftUIActivator.createErrorStatus( NLS.bind("The project {0} does not exist in your workspace.", projectName)); } else if (!project.isOpen()) { status = OpenShiftUIActivator .createErrorStatus(NLS.bind("The project {0} is not open.", projectName)); } } } return status; } } @Override protected void onPageWillGetActivated(Direction direction, PageChangingEvent event, DataBindingContext dbc) { if (direction == Direction.FORWARDS) { pageModel.reset(); } } @Override protected void onPageActivated(DataBindingContext dbc) { setPageTitle(); dbc.updateTargets(); } private void setPageTitle() { setTitle(NLS.bind(PAGE_TITLE_FORMAT, pageModel.getApplicationName())); } }