org.cloudfoundry.ide.eclipse.server.ui.internal.wizards.CloudFoundryApplicationServicesWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.cloudfoundry.ide.eclipse.server.ui.internal.wizards.CloudFoundryApplicationServicesWizardPage.java

Source

/*******************************************************************************
 * 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);
    }

}