com.ebmwebsourcing.petals.services.su.wizards.pages.ChoicePage.java Source code

Java tutorial

Introduction

Here is the source code for com.ebmwebsourcing.petals.services.su.wizards.pages.ChoicePage.java

Source

/******************************************************************************
 * Copyright (c) 2008-2013, Linagora
 *
 * 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:
 *       Linagora - initial API and implementation
 *******************************************************************************/

package com.ebmwebsourcing.petals.services.su.wizards.pages;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.IWizardNode;
import org.eclipse.jface.wizard.WizardSelectionPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import com.ebmwebsourcing.petals.common.internal.provisional.preferences.PreferencesManager;
import com.ebmwebsourcing.petals.common.internal.provisional.swt.DefaultSelectionListener;
import com.ebmwebsourcing.petals.common.internal.provisional.swt.DefaultTreeContentProvider;
import com.ebmwebsourcing.petals.common.internal.provisional.swt.PhantomText;
import com.ebmwebsourcing.petals.common.internal.provisional.ui.FixedShellTooltip;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.PetalsConstants;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.PlatformUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.StringUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.SwtFactory;
import com.ebmwebsourcing.petals.services.PetalsServicesPlugin;
import com.ebmwebsourcing.petals.services.su.extensions.ExtensionManager;
import com.ebmwebsourcing.petals.services.su.extensions.IComponentDescription;
import com.ebmwebsourcing.petals.services.su.extensions.PetalsKeyWords;
import com.ebmwebsourcing.petals.services.su.wizards.AbstractServiceUnitWizard;
import com.ebmwebsourcing.petals.services.su.wizards.FinishServiceCreationStrategy;
import com.ebmwebsourcing.petals.services.su.wizards.PetalsMode;

/**
 * Choose the kind of SU to create.
 * @author Vincent Zurczak - EBM WebSourcing
 */
public class ChoicePage extends WizardSelectionPage {

    public static final String PAGE_NAME = "ChoicePage";

    private final Map<PetalsKeyWords, Image> keywordToImage;
    private Image helpImg;
    private final Image bcImg;
    private final Image seImg;
    private Font boldFont;
    private FixedShellTooltip helpTooltip;

    private final PetalsMode petalsMode;
    private final FinishServiceCreationStrategy strategy;

    /**
     * Constructor.
     * @param strategy
     */
    public ChoicePage(PetalsMode petalsMode, FinishServiceCreationStrategy strategy) {
        super(PAGE_NAME);
        this.petalsMode = petalsMode;
        this.strategy = strategy;

        setTitle(petalsMode == PetalsMode.provides ? "Petals Service Provider" : "Petals Service Consumer");
        setDescription("Select the Petals component to configure and its version.");

        this.bcImg = PetalsServicesPlugin.loadImage("icons/obj16/choice_bc_16x16.png");
        this.seImg = PetalsServicesPlugin.loadImage("icons/obj16/choice_se_16x16.png");

        this.keywordToImage = new HashMap<PetalsKeyWords, Image>();
        for (PetalsKeyWords kw : PetalsKeyWords.values()) {
            try {
                Image img = kw.getImageDescriptor().createImage();
                this.keywordToImage.put(kw, img);

            } catch (Exception e) {
                PetalsServicesPlugin.log(e, IStatus.ERROR);
            }
        }
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.dialogs.IDialogPage
     * #createControl(org.eclipse.swt.widgets.Composite)
     */
    @Override
    public void createControl(Composite parent) {

        // Create the composite container and define its layout
        final Composite container = SwtFactory.createComposite(parent);
        setControl(container);
        SwtFactory.applyNewGridLayout(container, 2, false, 15, 0, 0, 15);
        SwtFactory.applyHorizontalGridData(container);

        // Add a tool tip to display in case of problem
        this.helpTooltip = new FixedShellTooltip(getShell(), true, 90) {
            @Override
            public void populateTooltip(Composite parent) {

                GridLayout layout = new GridLayout();
                layout.verticalSpacing = 2;
                parent.setLayout(layout);
                parent.setLayoutData(new GridData(GridData.FILL_BOTH));
                parent.setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

                try {
                    ImageDescriptor desc = AbstractUIPlugin.imageDescriptorFromPlugin(
                            PetalsConstants.PETALS_COMMON_PLUGIN_ID, "icons/petals/thinking_hard.png");

                    if (desc != null)
                        ChoicePage.this.helpImg = desc.createImage();

                    parent.setBackgroundMode(SWT.INHERIT_DEFAULT);
                    Label imgLabel = new Label(parent, SWT.NONE);
                    imgLabel.setImage(ChoicePage.this.helpImg);
                    imgLabel.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT, true, true));

                } catch (Exception e) {
                    PetalsServicesPlugin.log(e, IStatus.WARNING);
                }

                FontData[] fd = PlatformUtils.getModifiedFontData(getFont().getFontData(), SWT.BOLD);
                ChoicePage.this.boldFont = new Font(getShell().getDisplay(), fd);
                Label titleLabel = new Label(parent, SWT.NONE);
                titleLabel.setFont(ChoicePage.this.boldFont);
                GridData layoutData = new GridData(SWT.CENTER, SWT.DEFAULT, true, true);
                layoutData.verticalIndent = 5;
                titleLabel.setLayoutData(layoutData);
                titleLabel.setText("What does this error mean?");

                Label l = new Label(parent, SWT.WRAP);
                l.setText("This wizard will generate, among other things, Maven artifacts.");
                layoutData = new GridData();
                layoutData.verticalIndent = 8;
                l.setLayoutData(layoutData);

                RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL);
                rowLayout.marginLeft = 0;
                rowLayout.marginTop = 0;
                rowLayout.marginRight = 0;
                rowLayout.marginBottom = 0;
                rowLayout.spacing = 0;

                Composite rowComposite = new Composite(parent, SWT.NONE);
                rowComposite.setLayout(rowLayout);
                rowComposite.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT, true, true));

                new Label(rowComposite, SWT.WRAP).setText("Unfortunately, there is a problem with the ");
                Link link = new Link(rowComposite, SWT.WRAP | SWT.NO_FOCUS);
                link.setText("<A>the Petals Maven preferences</A>");
                new Label(rowComposite, SWT.WRAP).setText(".");
                new Label(parent, SWT.WRAP).setText("Please, make them correct.");

                link.addSelectionListener(new DefaultSelectionListener() {
                    @Override
                    public void widgetSelected(SelectionEvent e) {
                        try {
                            PreferencesUtil.createPreferenceDialogOn(new Shell(),
                                    "com.ebmwebsourcing.petals.services.prefs.maven", null, null).open();

                        } catch (Exception e1) {
                            PetalsServicesPlugin.log(e1, IStatus.ERROR);
                        }
                    }
                });
            }
        };

        // Prepare the input
        Comparator<AbstractServiceUnitWizard> comparator = new Comparator<AbstractServiceUnitWizard>() {
            @Override
            public int compare(AbstractServiceUnitWizard o1, AbstractServiceUnitWizard o2) {
                String v1 = o1.getComponentVersionDescription().getComponentVersion();
                String v2 = o2.getComponentVersionDescription().getComponentVersion();
                return -v1.compareTo(v2); // negative so that the most recent is first
            }
        };

        final Map<String, Collection<AbstractServiceUnitWizard>> componentNameToHandler = new TreeMap<String, Collection<AbstractServiceUnitWizard>>();
        final Map<PetalsKeyWords, Set<String>> keywordToComponentName = new TreeMap<PetalsKeyWords, Set<String>>();
        for (AbstractServiceUnitWizard handler : ExtensionManager.INSTANCE.findComponentWizards(this.petalsMode)) {
            for (PetalsKeyWords keyword : handler.getComponentVersionDescription().getKeyWords()) {
                Set<String> list = keywordToComponentName.get(keyword);
                if (list == null)
                    list = new TreeSet<String>();

                String componentName = handler.getComponentVersionDescription().getComponentName();
                list.add(componentName);
                keywordToComponentName.put(keyword, list);

                Collection<AbstractServiceUnitWizard> handlers = componentNameToHandler.get(componentName);
                if (handlers == null)
                    handlers = new TreeSet<AbstractServiceUnitWizard>(comparator);

                handlers.add(handler);
                componentNameToHandler.put(componentName, handlers);
            }
        }

        // Add the selection area
        final PhantomText searchText = new PhantomText(container, SWT.SINGLE | SWT.BORDER);
        searchText.setDefaultValue("Search...");
        GridDataFactory.swtDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).span(2, 1).applyTo(searchText);

        final TreeViewer componentsViewer = new TreeViewer(container, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
        GridDataFactory.fillDefaults().span(2, 1).hint(380, 300).applyTo(componentsViewer.getTree());
        componentsViewer.setLabelProvider(new LabelProvider() {
            @Override
            public String getText(Object element) {

                String result;
                if (element instanceof String) {
                    IComponentDescription desc = componentNameToHandler.get(element).iterator().next()
                            .getComponentVersionDescription();
                    String componentName = desc.getComponentName();
                    String componentAlias = desc.getComponentAlias();
                    String annotation = desc.getComponentAnnotation();

                    StringBuilder sb = new StringBuilder();
                    if (StringUtils.isEmpty(componentName))
                        sb.append(componentAlias); // Generic component
                    else
                        sb.append(componentAlias + "    -  " + componentName);

                    if (!StringUtils.isEmpty(annotation))
                        sb.append("    ( " + annotation + " )");

                    result = sb.toString();

                } else {
                    result = super.getText(element);
                }

                return result;
            }

            @Override
            public Image getImage(Object element) {

                Image result = null;
                if (element instanceof PetalsKeyWords) {
                    result = ChoicePage.this.keywordToImage.get(element);
                } else {
                    IComponentDescription desc = componentNameToHandler.get(element).iterator().next()
                            .getComponentVersionDescription();
                    result = desc.isBc() ? ChoicePage.this.bcImg : ChoicePage.this.seImg;
                }

                return result;
            }
        });

        componentsViewer.setContentProvider(new DefaultTreeContentProvider() {
            @Override
            public Object[] getElements(Object inputElement) {
                return keywordToComponentName.keySet().toArray();
            }

            @Override
            public Object[] getChildren(Object parentElement) {

                Object[] result;
                if (parentElement instanceof PetalsKeyWords) {
                    Collection<String> componentNames = keywordToComponentName.get(parentElement);
                    result = componentNames == null ? new Object[0] : componentNames.toArray();

                } else {
                    result = new Object[0];
                }

                return result;
            }

            @Override
            public boolean hasChildren(Object element) {
                return element instanceof PetalsKeyWords;
            }
        });

        componentsViewer.addFilter(new ViewerFilter() {
            @Override
            public boolean select(Viewer viewer, Object parentElement, Object element) {

                boolean result = false;
                String filter = searchText.getTextValue().trim().toLowerCase();
                if (filter.length() == 0)
                    result = true;

                else if (element instanceof PetalsKeyWords) {
                    Set<String> names = keywordToComponentName.get(element);
                    if (names != null) {
                        for (String s : names) {
                            if (select(viewer, null, s)) {
                                result = true;
                                break;
                            }
                        }
                    }
                }

                else if (element instanceof String)
                    result = ((String) element).toLowerCase().contains(filter);

                return result;
            }
        });

        componentsViewer.setInput(new Object());
        if (keywordToComponentName.size() > 0)
            componentsViewer.expandToLevel(keywordToComponentName.keySet().iterator().next(), 1);

        // Display the available versions
        new Label(container, SWT.NONE).setText("Component Version:");
        final ComboViewer versionCombo = new ComboViewer(container, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
        GridData layoutData = new GridData();
        layoutData.widthHint = 130;
        versionCombo.getCombo().setLayoutData(layoutData);
        versionCombo.setContentProvider(new ArrayContentProvider());
        versionCombo.setLabelProvider(new LabelProvider() {
            @Override
            public String getText(Object element) {
                return ((AbstractServiceUnitWizard) element).getComponentVersionDescription().getComponentVersion();
            }
        });

        final Label descriptionLabel = new Label(container, SWT.NONE);
        GridDataFactory.swtDefaults().span(2, 1).indent(0, 10).applyTo(descriptionLabel);

        // Selection listeners
        searchText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                componentsViewer.refresh();
                if (searchText.getTextValue().trim().length() == 0)
                    componentsViewer.collapseAll();
                else
                    componentsViewer.expandAll();
            }
        });

        componentsViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {

                // Get the selection
                Object o = ((IStructuredSelection) event.getSelection()).getFirstElement();
                Collection<?> input;
                if (o == null || o instanceof PetalsKeyWords)
                    input = Collections.emptyList();
                else
                    input = componentNameToHandler.get(o);

                // Default selection - there is always one
                versionCombo.setInput(input);
                versionCombo.getCombo().setVisibleItemCount(input.size() > 0 ? input.size() : 1);
                if (!input.isEmpty()) {
                    versionCombo.setSelection(new StructuredSelection(input.iterator().next()));
                    versionCombo.getCombo().notifyListeners(SWT.Selection, new Event());
                } else {
                    setPageComplete(false);
                    setSelectedNode(null);
                    descriptionLabel.setText("");
                    descriptionLabel.getParent().layout();
                }
            }
        });

        versionCombo.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                AbstractServiceUnitWizard suWizard = (AbstractServiceUnitWizard) ((IStructuredSelection) event
                        .getSelection()).getFirstElement();
                if (suWizard == null)
                    return;

                setPageComplete(true);
                setSelectedNode(getWizardNode(suWizard));

                String desc = ChoicePage.this.petalsMode == PetalsMode.provides
                        ? suWizard.getComponentVersionDescription().getProvideDescription()
                        : suWizard.getComponentVersionDescription().getConsumeDescription();
                descriptionLabel.setText(desc);
                descriptionLabel.getParent().layout();
            }
        });

        // Initialize
        if (PreferencesManager.isMavenTemplateConfigurationValid())
            this.helpTooltip.hide();

        componentsViewer.getTree().setFocus();
    }

    /**
     * @param wizard
     * @return
     */
    protected IWizardNode getWizardNode(AbstractServiceUnitWizard wizard) {
        wizard.setStrategy(this.strategy);
        return new ComponentWizardDescriptionWizardNode(wizard);
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.dialogs.DialogPage
     * #dispose()
     */
    @Override
    public void dispose() {

        this.helpTooltip.dispose();
        if (this.helpImg != null && !this.helpImg.isDisposed())
            this.helpImg.dispose();

        if (this.seImg != null && !this.seImg.isDisposed())
            this.seImg.dispose();

        if (this.bcImg != null && !this.bcImg.isDisposed())
            this.bcImg.dispose();

        if (this.boldFont != null && !this.boldFont.isDisposed())
            this.boldFont.dispose();

        for (Image img : this.keywordToImage.values()) {
            if (img != null && !img.isDisposed())
                img.dispose();
        }

        super.dispose();
    }
}