Java tutorial
/******************************************************************************* * Copyright (c) 2012, 2015 Pivotal Software, Inc. and IBM Corporation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License, * Version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Pivotal Software, Inc. - initial API and implementation ********************************************************************************/ package org.cloudfoundry.ide.eclipse.server.ui.internal.wizards; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.cloudfoundry.client.lib.domain.CloudService; import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryPlugin; import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryServer; import org.cloudfoundry.ide.eclipse.server.core.internal.client.CloudFoundryApplicationModule; import org.cloudfoundry.ide.eclipse.server.core.internal.client.LocalCloudService; import org.cloudfoundry.ide.eclipse.server.ui.internal.CloudFoundryImages; import org.cloudfoundry.ide.eclipse.server.ui.internal.ICoreRunnable; import org.cloudfoundry.ide.eclipse.server.ui.internal.Messages; import org.cloudfoundry.ide.eclipse.server.ui.internal.editor.ServiceViewerConfigurator; import org.cloudfoundry.ide.eclipse.server.ui.internal.editor.ServiceViewerSorter; import org.cloudfoundry.ide.eclipse.server.ui.internal.editor.ServicesTreeLabelProvider; import org.cloudfoundry.ide.eclipse.server.ui.internal.editor.TreeContentProvider; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.accessibility.AccessibleAdapter; import org.eclipse.swt.accessibility.AccessibleEvent; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.ToolBar; public class CloudFoundryApplicationServicesWizardPage extends PartsWizardPage { // This page is optional and can be completed at any time private final boolean canFinish = true; private final String serverTypeId; private final CloudFoundryServer cloudServer; private CheckboxTableViewer servicesViewer; private static final String DESCRIPTION = Messages.CloudFoundryApplicationServicesWizardPage_TEXT_BIND_DESCRIP; /** * Services, either existing or new, that a user has checked for binding. */ private final Set<String> selectedServicesToBind = new HashSet<String>(); /** * This is a list of services to add to the CF server. This may not * necessarily match all the services a user has selected to bind to an * application, as a user may add a service, but uncheck it for binding. */ private final Set<String> servicesToAdd = new HashSet<String>(); /** * All services both existing and added, used to refresh the input of the * viewer */ private final Map<String, CloudService> allServices = new HashMap<String, CloudService>(); private final ApplicationWizardDescriptor descriptor; public CloudFoundryApplicationServicesWizardPage(CloudFoundryServer cloudServer, CloudFoundryApplicationModule module, ApplicationWizardDescriptor descriptor) { super(Messages.COMMONTXT_SERVICES, Messages.CloudFoundryApplicationServicesWizardPage_TEXT_SERVICE_SELECTION, null); this.cloudServer = cloudServer; this.serverTypeId = module.getServerTypeId(); this.descriptor = descriptor; } public boolean isPageComplete() { return canFinish; } public void createControl(Composite parent) { setDescription(DESCRIPTION); ImageDescriptor banner = CloudFoundryImages.getWizardBanner(serverTypeId); if (banner != null) { setImageDescriptor(banner); } Composite tableArea = new Composite(parent, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(tableArea); GridDataFactory.fillDefaults().grab(true, true).applyTo(tableArea); Composite toolBarArea = new Composite(tableArea, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(toolBarArea); GridDataFactory.fillDefaults().grab(true, false).applyTo(toolBarArea); Label label = new Label(toolBarArea, SWT.NONE); GridDataFactory.fillDefaults().grab(false, false).align(SWT.BEGINNING, SWT.CENTER).applyTo(label); label.setText(Messages.CloudFoundryApplicationServicesWizardPage_LABEL_SELECT_SERVICE); Table table = new Table(tableArea, SWT.BORDER | SWT.SINGLE | SWT.CHECK); GridDataFactory.fillDefaults().grab(true, true).applyTo(table); ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT); ToolBar bar = toolBarManager.createControl(toolBarArea); GridDataFactory.fillDefaults().align(SWT.END, SWT.BEGINNING).grab(true, false).applyTo(bar); servicesViewer = new CheckboxTableViewer(table); servicesViewer.setContentProvider(new TreeContentProvider()); servicesViewer.setLabelProvider(new ServicesTreeLabelProvider(servicesViewer)); servicesViewer.setSorter(new ServiceViewerSorter(servicesViewer)); new ServiceViewerConfigurator().enableAutomaticViewerResizing().configureViewer(servicesViewer); servicesViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { Object[] services = servicesViewer.getCheckedElements(); if (services != null) { selectedServicesToBind.clear(); for (Object obj : services) { CloudService service = (CloudService) obj; selectedServicesToBind.add(service.getName()); } setServicesToBindInDescriptor(); } } }); Action addServiceAction = new Action(Messages.COMMONTXT_ADD_SERVICE, CloudFoundryImages.NEW_SERVICE) { public void run() { // Do not create the service right away. boolean deferAdditionOfService = true; CloudFoundryServiceWizard wizard = new CloudFoundryServiceWizard(cloudServer, deferAdditionOfService); WizardDialog dialog = new WizardDialog(getShell(), wizard); wizard.setParent(dialog); dialog.setPageSize(900, 600); dialog.setBlockOnOpen(true); if (dialog.open() == Window.OK) { // This cloud service does not yet exist. It will be created // outside of the wizard List<CloudService> addedService = wizard.getServices(); if (addedService != null) { addServices(addedService); } } } public String getToolTipText() { return Messages.CloudFoundryApplicationServicesWizardPage_TEXT_TOOLTIP; } }; // Add accessibility text to the table, so at least when navigating through the table, the screen reader // know these are services being selected servicesViewer.getControl().getAccessible().addAccessibleListener(new AccessibleAdapter() { @Override public void getName(AccessibleEvent e) { if (e.childID >= 0) { if (e.result != null) { e.result = NLS.bind(Messages.CloudFoundryApplicationServicesWizardPage_TEXT_TABLE_ACC_LABEL, e.result); } else { e.result = Messages.CloudFoundryApplicationServicesWizardPage_TEXT_SERVICE_SELECTION; } } } }); toolBarManager.add(addServiceAction); toolBarManager.update(true); setControl(tableArea); setInput(); } /** * Also automatically selects the added service to be bound to the * application. * @param service that was added and will also be automatically selected to * be bound to the application. */ protected void addServices(List<CloudService> services) { if (services == null || services.size() == 0) { return; } for (CloudService service : services) { allServices.put(service.getName(), service); servicesToAdd.add(service.getName()); selectedServicesToBind.add(service.getName()); } setServicesToBindInDescriptor(); setServicesToCreateInDescriptor(); setBoundServiceSelectionInUI(); } protected void setInput() { ICoreRunnable runnable = new ICoreRunnable() { public void run(IProgressMonitor monitor) throws CoreException { try { List<CloudService> existingServices = cloudServer.getBehaviour().getServices(monitor); // Clear only after retrieving an update list without errors allServices.clear(); servicesToAdd.clear(); selectedServicesToBind.clear(); // Only populate from the existing deployment info if // retrieving list of existing services was successful. // That way the services in the deployment info can be // verified if they exist, or if they need to be created. populateServicesFromDeploymentInfo(); // Update the mapping with existing Cloud Services. Local // services // (services that have not yet been created) will be // unaffected by this. if (existingServices != null) { for (CloudService actualService : existingServices) { if (actualService != null) { allServices.put(actualService.getName(), actualService); } } } // At this stage, since the existing Cloud Service mapping // has been updated // above, any remaining Local cloud services can be assumed // to not exist and // will require being created. Only create services IF they // are to be bound to the app. for (String name : selectedServicesToBind) { CloudService service = allServices.get(name); if (service instanceof LocalCloudService) { servicesToAdd.add(name); } } setServicesToCreateInDescriptor(); // Refresh UI Display.getDefault().asyncExec(new Runnable() { public void run() { // Clear any info in the dialogue setMessage(null); update(false, Status.OK_STATUS); setBoundServiceSelectionInUI(); } }); } catch (final CoreException e) { Display.getDefault().asyncExec(new Runnable() { public void run() { update(false, CloudFoundryPlugin.getErrorStatus(NLS.bind( Messages.CloudFoundryApplicationServicesWizardPage_ERROR_VERIFY_SERVICE, e.getMessage()), e)); } }); } } }; runAsynchWithWizardProgress(runnable, Messages.CloudFoundryApplicationServicesWizardPage_TEXT_VERIFY_SERVICE_PROGRESS); } protected void populateServicesFromDeploymentInfo() { List<CloudService> servicesToBind = descriptor.getDeploymentInfo().getServices(); if (servicesToBind != null) { for (CloudService service : servicesToBind) { allServices.put(service.getName(), service); selectedServicesToBind.add(service.getName()); } } setServicesToBindInDescriptor(); } protected void setBoundServiceSelectionInUI() { servicesViewer.setInput(allServices.values().toArray(new CloudService[] {})); List<CloudService> checkedServices = getServicesToBindAsCloudServices(); servicesViewer.setCheckedElements(checkedServices.toArray()); } protected List<CloudService> getServicesToBindAsCloudServices() { List<CloudService> servicesToBind = new ArrayList<CloudService>(); for (String serviceName : selectedServicesToBind) { CloudService service = allServices.get(serviceName); if (service != null) { servicesToBind.add(service); } } return servicesToBind; } protected void setServicesToBindInDescriptor() { List<CloudService> servicesToBind = getServicesToBindAsCloudServices(); descriptor.getDeploymentInfo().setServices(servicesToBind); } protected void setServicesToCreateInDescriptor() { List<CloudService> toCreate = new ArrayList<CloudService>(); for (String serviceName : servicesToAdd) { CloudService service = allServices.get(serviceName); if (service != null) { toCreate.add(service); } } descriptor.setCloudServicesToCreate(toCreate); } public void setErrorText(String newMessage) { // Clear the message setMessage(""); //$NON-NLS-1$ super.setErrorMessage(newMessage); } public void setMessageText(String newMessage) { setErrorMessage(""); //$NON-NLS-1$ super.setMessage(newMessage); } }