info.evanchik.eclipse.karaf.ui.KarafConfigurationTab.java Source code

Java tutorial

Introduction

Here is the source code for info.evanchik.eclipse.karaf.ui.KarafConfigurationTab.java

Source

/**
 * Copyright (c) 2011 Stephen Evanchik
 * 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:
 *  Stephen Evanchik - initial implementation
 */
package info.evanchik.eclipse.karaf.ui;

import info.evanchik.eclipse.karaf.core.KarafCorePluginUtils;
import info.evanchik.eclipse.karaf.core.KarafPlatformModel;
import info.evanchik.eclipse.karaf.core.KarafPlatformModelRegistry;
import info.evanchik.eclipse.karaf.core.configuration.FeaturesSection;
import info.evanchik.eclipse.karaf.core.features.Bundle;
import info.evanchik.eclipse.karaf.core.features.Feature;
import info.evanchik.eclipse.karaf.core.features.FeatureResolverImpl;
import info.evanchik.eclipse.karaf.core.features.Features;
import info.evanchik.eclipse.karaf.core.features.FeaturesRepository;
import info.evanchik.eclipse.karaf.core.features.XmlFeaturesRepository;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.commons.collections.ListUtils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;

/**
 * @author Stephen Evanchik (evanchsa@gmail.com)
 *
 */
public class KarafConfigurationTab extends AbstractLaunchConfigurationTab {

    /**
     *
     * @author Stephen Evanchik (evanchsa@gmail.com)
     *
     */
    private final class FeaturesContentProvider implements ITreeContentProvider {

        private List<FeaturesRepository> featuresRepositories;

        @Override
        public void dispose() {
            if (featuresResolverJob != null) {
                featuresResolverJob.cancel();
            }
        }

        @Override
        public Object[] getChildren(final Object parentElement) {
            if (parentElement == featuresRepositories) {
                return featuresRepositories.toArray();
            } else if (parentElement instanceof FeaturesRepository) {
                final FeaturesRepository featuresRepository = (FeaturesRepository) parentElement;
                return featuresRepository.getFeatures().getFeatures().toArray();
            } else if (parentElement instanceof Features) {
                final Features features = (Features) parentElement;
                return features.getFeatures().toArray();
            } else if (parentElement instanceof Feature) {
                final Feature feature = (Feature) parentElement;
                return ListUtils.union(feature.getFeatures(), feature.getBundles()).toArray();
            } else {
                return new Object[0];
            }
        }

        @Override
        public Object[] getElements(final Object inputElement) {
            if (inputElement == featuresRepositories && inputElement != null) {
                return featuresRepositories.toArray();
            } else if (inputElement instanceof FeaturesRepository) {
                final FeaturesRepository featuresRepo = (FeaturesRepository) inputElement;
                return new Object[] { featuresRepo.getFeatures() };
            } else if (inputElement instanceof Features) {
                final Features features = (Features) inputElement;
                return features.getFeatures().toArray();
            } else if (inputElement instanceof Feature) {
                final Feature feature = (Feature) inputElement;
                return ListUtils.union(feature.getFeatures(), feature.getBundles()).toArray();
            } else {
                return new Object[0];
            }
        }

        @Override
        public Object getParent(final Object element) {
            if (element instanceof FeaturesRepository) {
                return featuresRepositories;
            } else if (element instanceof Features) {
                final Features features = (Features) element;
                return features.getParent();
            } else if (element instanceof Feature) {
                return ((Feature) element).getParent();
            } else {
                return null;
            }
        }

        @Override
        public boolean hasChildren(final Object element) {
            if (element == featuresRepositories && element != null) {
                return featuresRepositories.size() > 0;
            } else if (element instanceof FeaturesRepository) {
                final FeaturesRepository featuresRepository = (FeaturesRepository) element;
                return featuresRepository.getFeatures().getFeatures().size() > 0;
            } else if (element instanceof Features) {
                final Features features = (Features) element;
                return features.getFeatures().size() > 0;
            } else if (element instanceof Feature) {
                final Feature feature = (Feature) element;
                return feature.getBundles().size() > 0 || feature.getFeatures().size() > 0;
            } else {
                return false;
            }
        }

        @Override
        @SuppressWarnings("unchecked")
        public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
            if (newInput != null) {
                featuresRepositories = (List<FeaturesRepository>) newInput;
            }
        }
    }

    /**
     *
     * @author Stephen Evanchik (evanchsa@gmail.com)
     *
     */
    private final class FeaturesLabelProvider extends LabelProvider implements ITableLabelProvider {

        @Override
        public Image getColumnImage(final Object element, final int columnIndex) {
            switch (columnIndex) {
            case 0:
                if (element instanceof FeaturesRepository) {
                    return KarafUIPluginActivator.getDefault().getImageRegistry()
                            .get(KarafUIPluginActivator.LOGO_16X16_IMG);
                } else if (element instanceof Feature) {
                    return KarafUIPluginActivator.getDefault().getImageRegistry()
                            .get(KarafUIPluginActivator.FEATURE_OBJ_IBM);
                } else if (element instanceof Bundle) {
                    return KarafUIPluginActivator.getDefault().getImageRegistry()
                            .get(KarafUIPluginActivator.BUNDLE_OBJ_IMG);
                } else {
                    return null;
                }

            default:
                return null;
            }
        }

        @Override
        public String getColumnText(final Object element, final int columnIndex) {

            switch (columnIndex) {
            case 0:
                if (element instanceof FeaturesRepository) {
                    final FeaturesRepository featuresRepository = (FeaturesRepository) element;
                    if (featuresRepository.getFeatures().getName() != null) {
                        return featuresRepository.getFeatures().getName();
                    } else {
                        return featuresRepository.getName();
                    }
                } else if (element instanceof Features) {
                    final Features features = (Features) element;
                    if (features.getName() != null) {
                        return features.getName();
                    } else if (features.getParent() != null) {
                        return features.getParent().getName();
                    } else {
                        return null;
                    }
                } else if (element instanceof Feature) {
                    final Feature feature = (Feature) element;
                    return feature.getName();
                } else if (element instanceof Bundle) {
                    final Bundle bundle = (Bundle) element;
                    final String label;
                    if (bundle.getBundleUrl().startsWith(MVN_URL_PREFIX)) {
                        final String[] bundleComponents = bundle.getBundleUrl().split("/"); //$NON-NLS-1$
                        label = bundleComponents[1];
                    } else {
                        label = element.toString();
                    }

                    return label;
                } else {
                    return element.toString();
                }
            case 1:
                if (element instanceof Feature) {
                    final Feature feature = (Feature) element;
                    return feature.getVersion();
                } else {
                    return null;
                }
            default:
                return null;
            }
        }
    }

    /**
     *
     * @author Stephen Evanchik (evanchsa@gmail.com)
     *
     */
    private final class FeaturesResolverJob extends Job {

        private volatile boolean cancel;

        private final List<FeaturesRepository> featuresRepositories = Collections
                .synchronizedList(new ArrayList<FeaturesRepository>());

        public FeaturesResolverJob() {
            super("Features Resolver");

            setSystem(true);
        }

        @Override
        public boolean shouldRun() {
            return !getControl().isDisposed();
        }

        @Override
        protected void canceling() {
            cancel = true;
        }

        @Override
        protected IStatus run(final IProgressMonitor monitor) {
            featuresRepositories.clear();

            featuresSection.load();

            for (final String repository : featuresSection.getRepositoryList()) {
                try {
                    final InputStream stream = new URL(repository).openConnection().getInputStream();

                    final String repositoryName;
                    if (repository.startsWith(MVN_URL_PREFIX)) {
                        final String[] repositoryComponents = repository.split("/"); //$NON-NLS-1$
                        repositoryName = repositoryComponents[1] + "-" + repositoryComponents[2]; //$NON-NLS-1$
                    } else {
                        repositoryName = repository;
                    }

                    final FeaturesRepository newRepo = new XmlFeaturesRepository(repositoryName, stream);
                    featuresRepositories.add(newRepo);
                } catch (final MalformedURLException e) {
                    // What to do here?
                } catch (final IOException e) {
                    // What to do here?
                }

                if (cancel) {
                    return Status.CANCEL_STATUS;
                }
            }

            return Status.OK_STATUS;
        }
    }

    public static final String ID = "info.evanchik.eclipse.karaf.ui.karafGeneralLaunchConfigurationTab"; //$NON-NLS-1$

    private static final String MVN_URL_PREFIX = "mvn:"; //$NON-NLS-1$

    private Composite control;

    private Button enableFeaturesManagement;

    private final FeaturesResolverJob featuresResolverJob = new FeaturesResolverJob();

    private FeaturesSection featuresSection;

    private ContainerCheckedTreeViewer installedFeatures;

    private KarafPlatformModel karafPlatformModel;

    private Button localConsole;

    private Button remoteConsole;

    private final List<String> selectedFeatures = Collections.synchronizedList(new ArrayList<String>());

    @Override
    public void createControl(final Composite parent) {
        control = new Composite(parent, SWT.NONE);

        final GridLayout layout = new GridLayout();
        control.setLayout(layout);

        final GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        control.setLayoutData(gd);

        createConsoleBlock(control);
        createFeaturesBlock(control);

        setControl(control);
        Dialog.applyDialogFont(control);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(control, ID);
    }

    @Override
    public String getId() {
        return ID;
    }

    @Override
    public Image getImage() {
        return KarafUIPluginActivator.getDefault().getImageRegistry().get(KarafUIPluginActivator.LOGO_16X16_IMG);
    }

    @Override
    public String getName() {
        return "Karaf";
    }

    @Override
    public void initializeFrom(final ILaunchConfiguration configuration) {
        try {
            localConsole.setSelection(configuration
                    .getAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_LOCAL_CONSOLE, true));
            remoteConsole.setSelection(configuration
                    .getAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_REMOTE_CONSOLE, false));
            enableFeaturesManagement.setSelection(configuration
                    .getAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_FEATURES_MANAGEMENT, true));

            initializeKarafPlatformModel();

            final String featuresString = configuration
                    .getAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_BOOT_FEATURES, "");
            final String[] features = featuresString.split(",");
            selectedFeatures.clear();
            selectedFeatures.addAll(Arrays.asList(features));

        } catch (final CoreException e) {
            // TODO: Do something sensible here
        }

        featuresResolverJob.addJobChangeListener(new JobChangeAdapter() {
            @Override
            public void done(final IJobChangeEvent event) {
                if (event.getResult().isOK()) {
                    featuresResolverJob.removeJobChangeListener(this);

                    try {
                        final String storedBootFeatures = configuration
                                .getAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_BOOT_FEATURES, "");

                        final FeatureResolverImpl fr = new FeatureResolverImpl(
                                featuresResolverJob.featuresRepositories);

                        final List<Object> checkedFeatures = new ArrayList<Object>();
                        for (final String s : storedBootFeatures.split(",")) {
                            final Object[] path = fr.getFeaturePath(s);
                            Collections.addAll(checkedFeatures, path);
                        }

                        Display.getDefault().syncExec(new Runnable() {
                            @Override
                            public void run() {
                                if (!getControl().isDisposed()) {
                                    installedFeatures.setInput(featuresResolverJob.featuresRepositories);
                                    installedFeatures.setCheckedElements(checkedFeatures.toArray());
                                }
                            };
                        });

                    } catch (final CoreException e) {
                        // TODO: Do something sensible
                    }
                }
            }
        });

        if (featuresResolverJob.getState() == Job.NONE) {
            featuresResolverJob.schedule();
        }
    }

    @Override
    public void performApply(final ILaunchConfigurationWorkingCopy configuration) {
        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_LOCAL_CONSOLE,
                localConsole.getSelection());
        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_REMOTE_CONSOLE,
                remoteConsole.getSelection());
        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_FEATURES_MANAGEMENT,
                enableFeaturesManagement.getSelection());
        final String featuresString = KarafCorePluginUtils.join(selectedFeatures, ",");
        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_BOOT_FEATURES, featuresString);
    }

    @Override
    public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) {
        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_LOCAL_CONSOLE, true);
        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_START_REMOTE_CONSOLE, false);
        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_FEATURES_MANAGEMENT, true);

        try {
            initializeKarafPlatformModel();
        } catch (final CoreException e) {
            // TODO: Do something sensible here
        }

        final List<String> featuresList = featuresSection.getBootFeatureNames();

        final String features = KarafCorePluginUtils.join(featuresList, ",");
        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_BOOT_FEATURES, features);
    }

    /**
     * Creates the necessary UI elements that control what kind of console to
     * use (i.e. remote, local or both)
     *
     * @param parent
     */
    private void createConsoleBlock(final Composite parent) {
        final Font font = parent.getFont();
        final Composite comp = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, true);
        comp.setLayout(layout);
        comp.setFont(font);

        final GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        comp.setLayoutData(gd);

        final Group group = new Group(comp, SWT.NONE);
        group.setFont(font);
        layout = new GridLayout(1, false);
        group.setLayout(layout);
        group.setLayoutData(new GridData(GridData.FILL_BOTH));

        group.setText("Console");

        final SelectionListener listener = new SelectionListener() {

            @Override
            public void widgetDefaultSelected(final SelectionEvent e) {
                scheduleUpdateJob();
            }

            @Override
            public void widgetSelected(final SelectionEvent e) {
                scheduleUpdateJob();
            }
        };

        localConsole = createCheckButton(group, "Local console");
        localConsole.addSelectionListener(listener);

        remoteConsole = createCheckButton(group, "Remote console");
        remoteConsole.addSelectionListener(listener);
    }

    /**
     * Creates the necessary UI controls to manipulate the features system.
     *
     * @param parent
     */
    private void createFeaturesBlock(final Composite parent) {
        final Font font = parent.getFont();
        final Composite comp = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, true);
        comp.setLayout(layout);
        comp.setFont(font);

        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        comp.setLayoutData(gd);

        final Group group = new Group(comp, SWT.NONE);
        group.setFont(font);
        layout = new GridLayout(1, false);
        group.setLayout(layout);
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        group.setText("Features");

        enableFeaturesManagement = new Button(group, SWT.CHECK);
        enableFeaturesManagement.setText("Enable Karaf Features management");
        enableFeaturesManagement.addListener(SWT.Selection, new Listener() {

            @Override
            public void handleEvent(final Event event) {
                if (event.widget == enableFeaturesManagement) {
                    final boolean enabledState = installedFeatures.getControl().getEnabled();
                    installedFeatures.getControl().setEnabled(!enabledState);
                    KarafConfigurationTab.this.updateLaunchConfigurationDialog();
                }
            }
        });

        installedFeatures = new ContainerCheckedTreeViewer(group, SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
        final Tree tree = installedFeatures.getTree();

        final TreeColumn column1 = new TreeColumn(tree, SWT.LEFT);
        column1.setText("Feature");
        column1.setWidth(300);

        final TreeColumn column2 = new TreeColumn(tree, SWT.LEFT);
        column2.setText("Version");
        column2.setWidth(175);

        gd = new GridData(GridData.FILL_BOTH);
        gd.heightHint = 300;
        tree.setLayoutData(gd);
        tree.setHeaderVisible(true);

        installedFeatures.setContentProvider(new FeaturesContentProvider());
        installedFeatures.setLabelProvider(new FeaturesLabelProvider());
        installedFeatures.setInput(null);
        installedFeatures.addCheckStateListener(new ICheckStateListener() {

            @Override
            public void checkStateChanged(final CheckStateChangedEvent event) {
                final Object[] elements = installedFeatures.getCheckedElements();

                for (final Object e : elements) {
                    if (e instanceof Feature && ((Feature) e).getParent() instanceof Features) {
                        final Feature f = (Feature) e;
                        if (!selectedFeatures.contains(f.getName())) {
                            selectedFeatures.add(f.getName());
                        }
                    } else if (e instanceof Bundle) {
                        final Bundle b = (Bundle) e;
                        if (b.getParent() instanceof Feature) {
                            final Feature f = (Feature) b.getParent();
                            if (!selectedFeatures.contains(f)) {
                                selectedFeatures.add(f.getName());
                            }
                        } else {
                            // Intentionally empty
                        }
                    } else {
                        // Intentionally empty
                    }
                }

                KarafConfigurationTab.this.updateLaunchConfigurationDialog();
            }
        });
    }

    /**
     * @throws CoreException
     */
    private void initializeKarafPlatformModel() throws CoreException {
        karafPlatformModel = KarafPlatformModelRegistry.findActivePlatformModel();

        featuresSection = (FeaturesSection) karafPlatformModel.getAdapter(FeaturesSection.class);

        featuresSection.load();
    }
}