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

Java tutorial

Introduction

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

Source

/*******************************************************************************
 * Copyright (c) 2012, 2014 Pivotal Software, Inc. 
 * 
 * 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.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.cloudfoundry.client.lib.domain.CloudService;
import org.cloudfoundry.client.lib.domain.CloudServiceOffering;
import org.cloudfoundry.client.lib.domain.CloudServicePlan;
import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryServer;
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.Messages;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.Observables;
import org.eclipse.core.databinding.observable.map.WritableMap;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.databinding.validation.MultiValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.LayoutConstants;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.statushandlers.StatusManager;

public class CloudFoundryServicePlanWizardPage extends WizardPage {

    protected DataBindingContext bindingContext;

    private final CloudFoundryServer cloudServer;

    private List<CloudServiceOffering> serviceOfferings;

    protected WritableMap map;

    private Text nameText;

    /**
     * The data model.
     */
    protected LocalCloudService service;

    private Composite planDetailsComposite;

    protected Group planGroup;

    private PageBook pageBook;

    private WritableValue planObservable = new WritableValue();

    private Combo typeCombo;

    private Pattern VALID_CHARS = Pattern.compile("[A-Za-z\\$_0-9\\-]+"); //$NON-NLS-1$

    protected CloudFoundryServicePlanWizardPage(CloudFoundryServer cloudServer) {
        super(Messages.CloudFoundryServicePlanWizardPage_TEXT_SERVICE_PAGE);
        this.cloudServer = cloudServer;
        setTitle(Messages.CloudFoundryServicePlanWizardPage_TITLE_SERVICE_CONFIG);
        setDescription(Messages.CloudFoundryServicePlanWizardPage_TEXT_FINISH_ADD);
        ImageDescriptor banner = CloudFoundryImages
                .getWizardBanner(cloudServer.getServer().getServerType().getId());
        if (banner != null) {
            setImageDescriptor(banner);
        }
        this.service = createService();
    }

    public void createControl(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayoutFactory.fillDefaults().numColumns(2).spacing(10, LayoutConstants.getSpacing().y)
                .applyTo(composite);

        Label label = new Label(composite, SWT.NONE);
        label.setText(Messages.COMMONTXT_NAME_WITH_COLON);

        nameText = new Text(composite, SWT.BORDER);
        GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText);
        nameText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                service.setName(nameText.getText());
            }
        });

        bindingContext = new DataBindingContext();
        map = new WritableMap();

        WizardPageSupport.create(this, bindingContext);

        bindingContext.bindValue(SWTObservables.observeText(nameText, SWT.Modify),
                Observables.observeMapEntry(map, "name"), //$NON-NLS-1$
                new UpdateValueStrategy().setAfterConvertValidator(new StringValidator()), null);

        label = new Label(composite, SWT.NONE);
        label.setText(Messages.CloudFoundryServicePlanWizardPage_LABEL_TYPE);

        typeCombo = new Combo(composite, SWT.READ_ONLY | SWT.BORDER);
        GridDataFactory.fillDefaults().grab(true, false).applyTo(typeCombo);
        typeCombo.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                int index = typeCombo.getSelectionIndex();
                if (index != -1) {
                    CloudServiceOffering configuration = serviceOfferings.get(index);
                    setCloudService(service, configuration);
                }
                refreshPlan();
            }
        });

        bindingContext
                .bindValue(SWTObservables.observeSelection(typeCombo), Observables.observeMapEntry(map, "type"), //$NON-NLS-1$
                        new UpdateValueStrategy().setAfterConvertValidator(
                                new ComboValidator(Messages.CloudFoundryServicePlanWizardPage_TEXT_SELECT_TYPE)),
                        null);

        pageBook = new PageBook(composite, SWT.NONE);
        GridDataFactory.fillDefaults().grab(true, true).span(2, 1).applyTo(pageBook);

        planGroup = new Group(pageBook, SWT.BORDER);
        GridDataFactory.fillDefaults().grab(true, true).applyTo(planGroup);
        planGroup.setLayout(new GridLayout());
        planGroup.setVisible(false);
        planGroup.setText(getPlanLabel());

        MultiValidator validator = new MultiValidator() {
            protected IStatus validate() {
                // access plan value to bind validator
                if (planObservable.getValue() == null) {
                    return ValidationStatus.cancel(getValidationErrorMessage());
                }
                return ValidationStatus.ok();
            }
        };
        bindingContext.addValidationStatusProvider(validator);

        Dialog.applyDialogFont(composite);
        setControl(composite);
    }

    public LocalCloudService getService() {
        return service;
    }

    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible && serviceOfferings == null) {
            // delay until dialog is actually visible
            Display.getDefault().asyncExec(new Runnable() {
                public void run() {
                    if (!getControl().isDisposed()) {
                        refresh();
                    }
                }
            });
        }
    }

    protected boolean supportsSpaces() {
        return cloudServer != null && cloudServer.hasCloudSpace();
    }

    protected void refresh() {
        if (updateConfiguration()) {
            typeCombo.removeAll();
            for (CloudServiceOffering offering : serviceOfferings) {
                String label = offering.getLabel() != null ? offering.getLabel() + " - " //$NON-NLS-1$
                        + offering.getDescription() : offering.getDescription();
                typeCombo.add(label);
            }
            refreshPlan();
        }
    }

    protected void refreshPlan() {
        int index = typeCombo.getSelectionIndex();
        if (index == -1) {
            pageBook.setVisible(false);
            planGroup.setVisible(false);

            // re-validate
            planObservable.setValue(null);
        } else {
            pageBook.setVisible(true);

            for (Control control : planGroup.getChildren()) {
                control.dispose();
            }
            CloudServiceOffering configuration = serviceOfferings.get(index);
            List<CloudServicePlan> servicePlans = getPlans(configuration);

            if (servicePlans.size() > 1) {
                pageBook.showPage(planGroup);
                planGroup.setVisible(true);

                Button defaultPlanControl = null;

                for (CloudServicePlan plan : servicePlans) {

                    String planLabelText = plan.getName();

                    Button planButton = new Button(planGroup, SWT.RADIO);

                    if (defaultPlanControl == null) {
                        defaultPlanControl = planButton;
                    }

                    planButton.setText(planLabelText);
                    planButton.setData(plan);
                    planButton.addSelectionListener(new SelectionAdapter() {
                        @Override
                        public void widgetSelected(SelectionEvent event) {
                            Button button = (Button) event.widget;
                            if (button.getSelection()) {
                                CloudServicePlan plan = (CloudServicePlan) button.getData();
                                setPlan(plan);

                            }
                        }
                    });
                }

                planDetailsComposite = new Composite(planGroup, SWT.NONE);
                GridLayoutFactory.fillDefaults().extendedMargins(0, 0, 10, 0).numColumns(2)
                        .applyTo(planDetailsComposite);

                // Set a default plan, if one exists
                if (defaultPlanControl != null) {
                    defaultPlanControl.setSelection(true);
                    CloudServicePlan plan = (CloudServicePlan) defaultPlanControl.getData();
                    setPlan(plan);

                }
            } else if (servicePlans.size() == 1) {
                planGroup.setVisible(false);
                CloudServicePlan plan = servicePlans.get(0);
                setPlan(plan);
            } else {
                pageBook.setVisible(false);
            }
        }
        ((Composite) getControl()).layout(true, true);

    }

    protected void setPlan(CloudServicePlan plan) {
        getService().setPlan(plan.getName());
        // re-validate
        planObservable.setValue(plan);
    }

    protected boolean updateConfiguration() {
        try {
            getContainer().run(true, false, new IRunnableWithProgress() {
                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                    try {
                        serviceOfferings = cloudServer.getBehaviour().getServiceOfferings(monitor);
                        Collections.sort(serviceOfferings, new Comparator<CloudServiceOffering>() {
                            public int compare(CloudServiceOffering o1, CloudServiceOffering o2) {
                                return o1.getDescription().compareTo(o2.getDescription());
                            }
                        });
                        sortServicePlans(serviceOfferings);

                    } catch (CoreException e) {
                        throw new InvocationTargetException(e);
                    } catch (OperationCanceledException e) {
                        throw new InterruptedException();
                    } finally {
                        monitor.done();
                    }
                }
            });
            return true;
        } catch (InvocationTargetException e) {
            IStatus status = cloudServer.error(NLS.bind(
                    Messages.CloudFoundryServicePlanWizardPage_ERROR_CONFIG_RETRIVE, e.getCause().getMessage()), e);
            StatusManager.getManager().handle(status, StatusManager.LOG);
            setMessage(status.getMessage(), IMessageProvider.ERROR);
        } catch (InterruptedException e) {
            // ignore
        }
        return false;
    }

    protected class ComboValidator implements IValidator {

        private final String message;

        public ComboValidator(String message) {
            this.message = message;
        }

        public IStatus validate(Object value) {
            if (value instanceof String && ((String) value).length() > 0) {
                return Status.OK_STATUS;
            }
            return ValidationStatus.cancel(message);
        }

    }

    protected class StringValidator implements IValidator {

        public IStatus validate(Object value) {
            if (value instanceof String) {
                if (((String) value).length() == 0) {
                    return ValidationStatus.cancel(Messages.CloudFoundryServicePlanWizardPage_TEXT_ENTER_NAME);
                }
                Matcher matcher = VALID_CHARS.matcher((String) value);
                if (!matcher.matches()) {
                    return ValidationStatus.error(Messages.CloudFoundryServicePlanWizardPage_ERROR_INVALID_CHAR);
                }
            }
            return Status.OK_STATUS;
        }

    }

    protected void sortServicePlans(List<CloudServiceOffering> configurations) {

        for (CloudServiceOffering offering : configurations) {
            Collections.sort(offering.getCloudServicePlans(), new Comparator<CloudServicePlan>() {
                public int compare(CloudServicePlan o1, CloudServicePlan o2) {
                    return o1.getName().compareTo(o2.getName());
                }
            });
        }
    }

    protected List<CloudServicePlan> getPlans(CloudServiceOffering offering) {
        List<CloudServicePlan> plans = new ArrayList<CloudServicePlan>();

        List<CloudServicePlan> cloudPlans = offering.getCloudServicePlans();

        if (cloudPlans != null) {
            for (CloudServicePlan plan : cloudPlans) {
                plans.add(plan);
            }
        }
        return plans;

    }

    protected String getValidationErrorMessage() {
        return Messages.CloudFoundryServicePlanWizardPage_ERROR_SELECT_PLAN;
    }

    protected String getPlanLabel() {
        return Messages.CloudFoundryServicePlanWizardPage_LABEL_PLAN;
    }

    protected void setCloudService(CloudService service, CloudServiceOffering offering) {

        service.setVersion(offering.getVersion());
        service.setLabel(offering.getLabel());
        service.setProvider(offering.getProvider());

    }

    protected LocalCloudService createService() {
        LocalCloudService service = new LocalCloudService(""); //$NON-NLS-1$
        return service;
    }

}