You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2012/01/04 14:22:42 UTC

svn commit: r1227144 [7/18] - in /karaf/eik/trunk: ./ features/ features/info.evanchik.eclipse.karaf.feature/ features/info.evanchik.eclipse.karaf.jmx.feature/ features/info.evanchik.eclipse.karaf.update/ features/info.evanchik.eclipse.karaf.update/fea...

Added: karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/pom.xml
URL: http://svn.apache.org/viewvc/karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/pom.xml?rev=1227144&view=auto
==============================================================================
--- karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/pom.xml (added)
+++ karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/pom.xml Wed Jan  4 13:22:10 2012
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+     Copyright (c) 2009 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>info.evanchik.eclipse.karaf</groupId>
+    <artifactId>eik-plugins-parent</artifactId>
+    <version>1.0.0</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>info.evanchik.eclipse.karaf</groupId>
+  <artifactId>info.evanchik.eclipse.karaf.ui</artifactId>
+  <version>0.5.3-SNAPSHOT</version>
+  <packaging>eclipse-plugin</packaging>
+  <name>Eclipse Integration for Karaf :: Base UI for Eclipse Integration</name>
+  <description>Provides base UI functionalty for Eclipse Integration</description>
+  <build>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>${pom.basedir}/src/main/filtered-resources</directory>
+        <includes>
+          <include>**/*</include>
+        </includes>
+      </resource>
+    </resources>
+    <plugins>
+      <!-- enable source bundle generation -->
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-source-plugin</artifactId>
+        <version>${tycho-version}</version>
+        <executions>
+          <execution>
+            <id>plugin-source</id>
+            <goals>
+              <goal>plugin-source</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Added: karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/schema/service.exsd
URL: http://svn.apache.org/viewvc/karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/schema/service.exsd?rev=1227144&view=auto
==============================================================================
--- karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/schema/service.exsd (added)
+++ karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/schema/service.exsd Wed Jan  4 13:22:10 2012
@@ -0,0 +1,102 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="info.evanchik.eclipse.karaf.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="info.evanchik.eclipse.karaf.ui" id="service" name="Apache Felix Karaf Workbench Service"/>
+      </appinfo>
+      <documentation>
+         [Enter description of this extension point.]
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <choice>
+            <element ref="launchCustomizer"/>
+         </choice>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="launchCustomizer">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":info.evanchik.eclipse.karaf.workbench.KarafWorkbenchServiceFactory"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+
+</schema>

Added: karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/IKarafProject.java
URL: http://svn.apache.org/viewvc/karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/IKarafProject.java?rev=1227144&view=auto
==============================================================================
--- karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/IKarafProject.java (added)
+++ karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/IKarafProject.java Wed Jan  4 13:22:10 2012
@@ -0,0 +1,70 @@
+/**
+ * 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 java.util.Properties;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * @author Stephen Evanchik (evanchsa@gmail.com)
+ *
+ */
+public interface IKarafProject extends IAdaptable {
+
+    /**
+     *
+     * @param name
+     * @return
+     */
+    public IFile getFile(String name);
+
+    /**
+     *
+     * @param name
+     * @return
+     */
+    public IFolder getFolder(String name);
+
+    /**
+     *
+     * @return
+     */
+    public IPath getLocation();
+
+    /**
+     *
+     * @return
+     */
+    public String getName();
+
+    /**
+     *
+     * @return
+     */
+    public IPath getPlatformRootDirectory();
+
+    /**
+     *
+     * @return
+     */
+    public IProject getProjectHandle();
+
+    /**
+     *
+     * @return
+     */
+    public Properties getRuntimeProperties();
+}

Added: karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafConfigurationTab.java
URL: http://svn.apache.org/viewvc/karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafConfigurationTab.java?rev=1227144&view=auto
==============================================================================
--- karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafConfigurationTab.java (added)
+++ karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafConfigurationTab.java Wed Jan  4 13:22:10 2012
@@ -0,0 +1,824 @@
+/**
+ * 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.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.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+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.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+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.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author Stephen Evanchik (evanchsa@gmail.com)
+ *
+ */
+public class KarafConfigurationTab extends AbstractLaunchConfigurationTab {
+
+    /**
+     *
+     * @author Stephen Evanchik (evanchsa@gmail.com)
+     *
+     */
+    private static final class AvailableFeature {
+
+        private final String feature;
+
+        private final String featuresRepository;
+
+        /**
+         *
+         * @param feature
+         * @param featuresRepository
+         */
+        public AvailableFeature(final Feature feature, final FeaturesRepository featuresRepository) {
+            if (feature == null) {
+                throw new NullPointerException("feature");
+            }
+
+            this.feature = feature.getName();
+
+            if (featuresRepository != null) {
+                this.featuresRepository = featuresRepository.getName();
+            } else {
+                this.featuresRepository = "";
+            }
+        }
+
+        /**
+         *
+         * @param feature
+         * @param featuresRepository
+         */
+        public AvailableFeature(final String feature, final String featuresRepository) {
+            this.feature = feature;
+            this.featuresRepository = featuresRepository;
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if (this == obj) {
+                return true;
+            }
+
+            if (obj == null) {
+                return false;
+            }
+
+            if (!(obj instanceof AvailableFeature)) {
+                return false;
+            }
+
+            final AvailableFeature other = (AvailableFeature) obj;
+            if (feature == null) {
+                if (other.feature != null) {
+                    return false;
+                }
+            } else if (!feature.equals(other.feature)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        public String getFeatureName() {
+            return feature;
+        }
+
+        public String getFeatureVersion() {
+            return feature;
+        }
+
+        public String getRepositoryName() {
+            return featuresRepository;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + (feature == null ? 0 : feature.hashCode());
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            return feature;
+        }
+    }
+
+    /**
+     *
+     * @author Stephen Evanchik (evanchsa@gmail.com)
+     *
+     */
+    private final class AvailableFeaturesContentProvider implements IStructuredContentProvider {
+
+        private final List<AvailableFeature> availableFeatures =
+            Collections.synchronizedList(new ArrayList<AvailableFeature>());
+
+        @Override
+        public void dispose() {
+        }
+
+        @Override
+        public Object[] getElements(final Object inputElement) {
+            return availableFeatures.toArray();
+        }
+
+        @Override
+        public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
+            if (newInput == null) {
+                return;
+            }
+
+            availableFeatures.clear();
+
+            @SuppressWarnings("unchecked")
+            final List<FeaturesRepository> featuresRepositories = (List<FeaturesRepository>) newInput;
+            for (final FeaturesRepository  repository : featuresRepositories) {
+                for (final Feature f : repository.getFeatures().getFeatures()) {
+                    availableFeatures.add(new AvailableFeature(f, repository));
+                }
+            }
+        }
+    }
+
+    /**
+     *
+     * @author Stephen Evanchik (evanchsa@gmail.com)
+     *
+     */
+    private final class AvailableFeaturesLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+        @Override
+        public Image getColumnImage(final Object element, final int columnIndex) {
+            if (columnIndex == 0) {
+                return KarafUIPluginActivator.getDefault().getImageRegistry().get(KarafUIPluginActivator.FEATURE_OBJ_IBM);
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        public String getColumnText(final Object element, final int columnIndex) {
+
+            final AvailableFeature feature = (AvailableFeature) element;
+            switch (columnIndex) {
+            case 0:
+                return feature.getFeatureName();
+            case 1:
+                return feature.getFeatureVersion();
+            case 2:
+                return feature.getRepositoryName();
+            default:
+                return null;
+            }
+        }
+    }
+
+    /**
+     *
+     * @author Stephen Evanchik (evanchsa@gmail.com)
+     *
+     */
+    private final class BootFeaturesContentProvider implements IStructuredContentProvider {
+
+        @Override
+        public void dispose() {
+        }
+
+        @Override
+        public Object[] getElements(final Object inputElement) {
+            return bootFeaturesList.toArray();
+        }
+
+        @Override
+        public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
+        }
+    }
+
+    /**
+     *
+     * @author Stephen Evanchik (evanchsa@gmail.com)
+     *
+     */
+    private final class BootFeaturesLabelProvider extends LabelProvider {
+
+        @Override
+        public Image getImage(final Object element) {
+            return KarafUIPluginActivator.getDefault().getImageRegistry().get(KarafUIPluginActivator.FEATURE_OBJ_IBM);
+        }
+    }
+
+    public static final String ID = "info.evanchik.eclipse.karaf.ui.karafGeneralLaunchConfigurationTab"; //$NON-NLS-1$
+
+    private CheckboxTableViewer availableFeaturesViewer;
+
+    private Button bootFeatureOrderDecreaseButton;
+
+    private Button bootFeatureOrderIncreaseButton;
+
+    private Button bootFeatureRemoveButton;
+
+    private final List<String> bootFeaturesList = Collections.synchronizedList(new ArrayList<String>());
+
+    private TableViewer bootFeaturesViewer;
+
+    private Composite control;
+
+    private Button enableFeaturesManagement;
+
+    private KarafPlatformModel karafPlatformModel;
+
+    private IKarafProject karafProject;
+
+    private Button localConsole;
+
+    private Button remoteConsole;
+
+    private Text remoteConsolePassword;
+
+    private Text remoteConsoleUsername;
+
+    @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) {
+
+        FileInputStream fin = null;
+        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 storedBootFeatures = configuration.getAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_BOOT_FEATURES, "");
+            final String[] features = storedBootFeatures.split(",");
+            for (final String feature : features) {
+                // TODO: Not really efficient
+                if (!feature.isEmpty() && !bootFeaturesList.contains(feature)) {
+                    bootFeaturesList.add(feature);
+                }
+            }
+
+            // TODO: This should be factored out and it should be easy to get a List of FeaturesRepository
+            final IFolder featuresFolder = karafProject.getFolder("features");
+            if (featuresFolder.exists()) {
+                final List<FeaturesRepository> featuresRepositories = new ArrayList<FeaturesRepository>();
+                final IResource[] resources = featuresFolder.members();
+                for (final IResource resource : resources) {
+                    if (resource.getFileExtension().equalsIgnoreCase("xml")) {
+                        fin = new FileInputStream(resource.getRawLocation().toFile());
+                        final XmlFeaturesRepository xmlFeatureRepository = new XmlFeaturesRepository(resource.getName(), fin);
+                        featuresRepositories.add(xmlFeatureRepository);
+                        fin.close();
+                    }
+                }
+
+                Collections.sort(featuresRepositories, new Comparator<FeaturesRepository>() {
+                    @Override
+                    public int compare(final FeaturesRepository o1, final FeaturesRepository o2) {
+                        return o1.getName().compareTo(o2.getName());
+                    }
+                });
+
+                final FeatureResolverImpl fr = new FeatureResolverImpl(featuresRepositories);
+
+                final List<Object> checkedFeatures = new ArrayList<Object>();
+                for (final String s : bootFeaturesList) {
+                    final Feature f = fr.findFeature(s);
+
+                    if (f == null) {
+                        // TODO: Set some sort of warning
+                        continue;
+                    }
+
+                    final Features featuresContainer = (Features) f.getParent();
+                    final FeaturesRepository featuresRepository = featuresContainer.getParent();
+
+                    checkedFeatures.add(new AvailableFeature(f, featuresRepository));
+                }
+
+                Display.getDefault().syncExec(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (!getControl().isDisposed()) {
+                            bootFeaturesViewer.setInput(bootFeaturesList);
+                            bootFeaturesViewer.refresh();
+
+                            availableFeaturesViewer.setInput(featuresRepositories);
+                            availableFeaturesViewer.setCheckedElements(checkedFeatures.toArray());
+                        }
+                    };
+                });
+            }
+        } catch (final IOException e) {
+            KarafUIPluginActivator.getLogger().error("Uable to load file", e);
+        } catch (final CoreException e) {
+            KarafUIPluginActivator.getLogger().error("Unable to initialize launch configuration tab", e);
+            return;
+        } finally {
+            if (fin != null) {
+                try {
+                    fin.close();
+                } catch (final IOException e) {
+                    // Nothing to do here
+                }
+            }
+        }
+    }
+
+    @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_REMOTE_CONSOLE_PASSWORD, remoteConsolePassword.getText());
+        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_REMOTE_CONSOLE_USERNAME, remoteConsoleUsername.getText());
+        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_FEATURES_MANAGEMENT, enableFeaturesManagement.getSelection());
+        final String featuresString = KarafCorePluginUtils.join(bootFeaturesList, ",");
+        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_BOOT_FEATURES, featuresString);
+    }
+
+    @Override
+    public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) {
+
+        try {
+            initializeKarafPlatformModel();
+        } catch (final CoreException e) {
+            KarafUIPluginActivator.getLogger().error("Unable to initialize Karaf Platform model", e);
+            return;
+        }
+
+        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);
+
+        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_REMOTE_CONSOLE_USERNAME, "karaf");
+        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_REMOTE_CONSOLE_PASSWORD, "karaf");
+
+        final FeaturesSection featuresSection = (FeaturesSection) karafPlatformModel.getAdapter(FeaturesSection.class);
+        featuresSection.load();
+
+        final List<String> featuresList = featuresSection.getBootFeatureNames();
+
+        final String features = KarafCorePluginUtils.join(featuresList, ",");
+        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_BOOT_FEATURES, features);
+    }
+
+    /**
+     * @param group
+     */
+    private void createAvailableFeaturesControls(final Group group) {
+        GridData gd;
+        availableFeaturesViewer = CheckboxTableViewer.newCheckList(group, SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
+        final Table tree = availableFeaturesViewer.getTable();
+
+        final TableColumn column1 = new TableColumn(tree, SWT.LEFT);
+        column1.setText("Feature");
+        column1.setWidth(250);
+
+        final TableColumn column2 = new TableColumn(tree, SWT.LEFT);
+        column2.setText("Version");
+        column2.setWidth(150);
+
+        final TableColumn column3 = new TableColumn(tree, SWT.LEFT);
+        column3.setText("Repository");
+        column3.setWidth(150);
+
+        gd = new GridData(GridData.FILL_BOTH);
+        gd.heightHint = 200;
+        tree.setLayoutData(gd);
+        tree.setHeaderVisible(true);
+
+        availableFeaturesViewer.setContentProvider(new AvailableFeaturesContentProvider());
+        availableFeaturesViewer.setLabelProvider(new AvailableFeaturesLabelProvider());
+        availableFeaturesViewer.setInput(null);
+        availableFeaturesViewer.addCheckStateListener(new ICheckStateListener() {
+
+            @Override
+            public void checkStateChanged(final CheckStateChangedEvent event) {
+                final AvailableFeature f = (AvailableFeature) event.getElement();
+                if (event.getChecked()) {
+                    if (!bootFeaturesList.contains(f.getFeatureName())) {
+                        bootFeaturesList.add(f.getFeatureName());
+                        bootFeaturesViewer.refresh();
+                    }
+                } else {
+                    bootFeaturesList.remove(f.getFeatureName());
+                    bootFeaturesViewer.refresh();
+                }
+                KarafConfigurationTab.this.updateLaunchConfigurationDialog();
+            }
+        });
+    }
+
+    /**
+     * @param group
+     */
+    private void createBootFeatureManagementControls(final Group group) {
+        // Boot feature management
+        final Composite viewerComposite = new Composite(group, SWT.NONE);
+        GridLayout layout = new GridLayout(2, false);
+        layout.marginHeight = layout.marginWidth = 0;
+
+        viewerComposite.setLayout(layout);
+
+        GridData data = new GridData(GridData.FILL_BOTH);
+        data.heightHint = 200;
+        data.widthHint = 200;
+        viewerComposite.setLayoutData(data);
+
+        bootFeaturesViewer = new TableViewer(viewerComposite, SWT.BORDER | SWT.MULTI);
+        bootFeaturesViewer.setLabelProvider(new BootFeaturesLabelProvider());
+        bootFeaturesViewer.setContentProvider(new BootFeaturesContentProvider());
+        bootFeaturesViewer.setInput(bootFeaturesList);
+        bootFeaturesViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+            @Override
+            public void selectionChanged(final SelectionChangedEvent event) {
+                handleBootFeatureSelectionChange();
+            }
+        });
+
+        data = new GridData(GridData.FILL_BOTH);
+        data.heightHint = 50;
+        data.widthHint = 200;
+        bootFeaturesViewer.getTable().setLayoutData(data);
+
+        final Composite buttonComposite = new Composite(viewerComposite, SWT.RIGHT);
+        layout = new GridLayout();
+        layout.marginHeight = layout.marginWidth = 0;
+        buttonComposite.setLayout(layout);
+
+        data = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.GRAB_VERTICAL);
+        buttonComposite.setLayoutData(data);
+
+        bootFeatureOrderIncreaseButton = new Button(buttonComposite, SWT.PUSH);
+        bootFeatureOrderIncreaseButton.setText("Up");
+        bootFeatureOrderIncreaseButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        bootFeatureOrderIncreaseButton.addListener(SWT.Selection, new Listener() {
+
+            @Override
+            public void handleEvent(final Event event) {
+                if (event.widget == bootFeatureOrderIncreaseButton) {
+                    handleBootFeatureMove(-1);
+                    KarafConfigurationTab.this.updateLaunchConfigurationDialog();
+                }
+            }
+        });
+
+        bootFeatureRemoveButton = new Button(buttonComposite, SWT.PUSH);
+        bootFeatureRemoveButton.setText("Remove");
+        bootFeatureRemoveButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        bootFeatureRemoveButton.addListener(SWT.Selection, new Listener() {
+
+            @Override
+            public void handleEvent(final Event event) {
+                if (event.widget == bootFeatureRemoveButton) {
+                    removeSelectedBootFeatures();
+                    KarafConfigurationTab.this.updateLaunchConfigurationDialog();
+                }
+            }
+        });
+
+        bootFeatureOrderDecreaseButton = new Button(buttonComposite, SWT.PUSH);
+        bootFeatureOrderDecreaseButton.setText("Down");
+        bootFeatureOrderDecreaseButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        bootFeatureOrderDecreaseButton.addListener(SWT.Selection, new Listener() {
+
+            @Override
+            public void handleEvent(final Event event) {
+                if (event.widget == bootFeatureOrderDecreaseButton) {
+                    handleBootFeatureMove(1);
+                    KarafConfigurationTab.this.updateLaunchConfigurationDialog();
+                }
+            }
+        });
+    }
+
+    /**
+     * 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 Composite comp = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout(1, true);
+        comp.setLayout(layout);
+        comp.setFont(parent.getFont());
+
+        final GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+        comp.setLayoutData(gd);
+
+        final Group group = new Group(comp, SWT.NONE);
+        layout = new GridLayout(1, false);
+        group.setLayout(layout);
+        group.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        group.setText("Console");
+
+        localConsole = createCheckButton(group, "Local console");
+        localConsole.addSelectionListener(new SelectionListener() {
+
+            @Override
+            public void widgetDefaultSelected(final SelectionEvent e) {
+                scheduleUpdateJob();
+            }
+
+            @Override
+            public void widgetSelected(final SelectionEvent e) {
+                scheduleUpdateJob();
+            }
+        });
+
+        final KeyListener keyListener = new KeyListener() {
+
+            @Override
+            public void keyPressed(final KeyEvent e) {
+                scheduleUpdateJob();
+            }
+
+            @Override
+            public void keyReleased(final KeyEvent e) {
+                scheduleUpdateJob();
+            }
+        };
+
+        remoteConsole = createCheckButton(group, "Remote console");
+
+        final Composite credentialsBlock = new Composite(group, SWT.NONE);
+        credentialsBlock.setLayout(new GridLayout(2, true));
+
+        Label l = new Label(credentialsBlock, SWT.NONE);
+        l.setText("Username");
+        remoteConsoleUsername = new Text(credentialsBlock, SWT.BORDER);
+        remoteConsoleUsername.setText("karaf");
+        remoteConsoleUsername.setLayoutData(new GridData(175, 20));
+        remoteConsoleUsername.addKeyListener(keyListener);
+
+        l = new Label(credentialsBlock, SWT.NONE);
+        l.setText("Password");
+        remoteConsolePassword = new Text(credentialsBlock, SWT.BORDER|SWT.PASSWORD);
+        remoteConsolePassword.setText("karaf");
+        remoteConsolePassword.setLayoutData(new GridData(175, 20));
+        remoteConsolePassword.addKeyListener(keyListener);
+
+        remoteConsole.addSelectionListener(new SelectionListener() {
+
+            @Override
+            public void widgetDefaultSelected(final SelectionEvent e) {
+                updateRemoteConsoleControls();
+            }
+
+            @Override
+            public void widgetSelected(final SelectionEvent e) {
+                updateRemoteConsoleControls();
+            }
+
+            private void updateRemoteConsoleControls() {
+                final boolean enable = remoteConsole.getSelection();
+                remoteConsoleUsername.setEnabled(enable);
+                remoteConsolePassword.setEnabled(enable);
+
+                scheduleUpdateJob();
+            }
+        });
+    }
+
+    /**
+     * Creates the necessary UI controls to manipulate the features system.
+     *
+     * @param parent
+     */
+    private void createFeaturesBlock(final Composite parent) {
+
+        final Font font = parent.getFont();
+        final GridLayout layout = new GridLayout(2, false);
+
+        final Group group = new Group(parent, SWT.NONE);
+        group.setFont(font);
+        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 = availableFeaturesViewer.getControl().getEnabled();
+                    availableFeaturesViewer.getControl().setEnabled(!enabledState);
+                    bootFeaturesViewer.getControl().setEnabled(!enabledState);
+                    bootFeatureOrderDecreaseButton.setEnabled(!enabledState);
+                    bootFeatureOrderIncreaseButton.setEnabled(!enabledState);
+                    bootFeatureRemoveButton.setEnabled(!enabledState);
+
+                    KarafConfigurationTab.this.updateLaunchConfigurationDialog();
+                }
+            }
+        });
+        enableFeaturesManagement.setLayoutData(new GridData(SWT.BEGINNING));
+
+        final Label bootFeatureRankLabel = new Label(group, SWT.NONE);
+        bootFeatureRankLabel.setText("Boot Feature Rank");
+        bootFeatureRankLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        createAvailableFeaturesControls(group);
+        createBootFeatureManagementControls(group);
+    }
+
+    /**
+     *
+     */
+    private void handleBootFeatureSelectionChange() {
+        final IStructuredSelection selection = (IStructuredSelection) bootFeaturesViewer.getSelection();
+
+        final boolean notEmpty = !selection.isEmpty();
+
+        @SuppressWarnings("unchecked")
+        final Iterator<String> selectionElements = selection.iterator();
+
+        boolean first = false;
+        boolean last = false;
+        final int lastBootFeature = bootFeaturesList.size() - 1;
+
+        while (selectionElements.hasNext()) {
+            final Object element = selectionElements.next();
+            if(!first && bootFeaturesList.indexOf(element) == 0) {
+                first = true;
+            }
+
+            if (!last && bootFeaturesList.indexOf(element) == lastBootFeature) {
+                last = true;
+            }
+        }
+
+        bootFeatureOrderIncreaseButton.setEnabled(notEmpty && !first);
+        bootFeatureOrderDecreaseButton.setEnabled(notEmpty && !last);
+    }
+
+    /**
+     *
+     * @param direction
+     */
+    private void handleBootFeatureMove(final int direction) {
+        if (direction != -1 || direction != 1) {
+            throw new IllegalArgumentException("direction must be -1 or 1. Value: " + direction);
+        }
+
+        final IStructuredSelection selection = (IStructuredSelection)bootFeaturesViewer.getSelection();
+
+        @SuppressWarnings("unchecked")
+        final List<String> selectionList = selection.toList();
+        final String[] movedBootFeatures = new String[bootFeaturesList.size()];
+
+        for (final String config : selectionList) {
+            final int i = bootFeaturesList.indexOf(config);
+            movedBootFeatures[i + direction] = config;
+        }
+
+        bootFeaturesList.removeAll(selectionList);
+
+        for (int j = 0; j < movedBootFeatures.length; j++) {
+            final String config = movedBootFeatures[j];
+            if (config != null) {
+                bootFeaturesList.add(j, config);
+            }
+        }
+
+        bootFeaturesViewer.refresh();
+        handleBootFeatureSelectionChange();
+    }
+
+    /**
+     * @throws CoreException
+     */
+    private void initializeKarafPlatformModel() throws CoreException {
+        karafPlatformModel = KarafPlatformModelRegistry.findActivePlatformModel();
+        if (karafPlatformModel == null) {
+            throw new CoreException(new Status(IStatus.ERROR, KarafUIPluginActivator.PLUGIN_ID, "Unable to locate active Karaf Platform Model"));
+        }
+
+        karafProject = (IKarafProject) Platform.getAdapterManager().getAdapter(karafPlatformModel, IKarafProject.class);
+        if (karafProject== null) {
+            throw new CoreException(new Status(IStatus.ERROR, KarafUIPluginActivator.PLUGIN_ID, "Unable to locate Karaf Project in Workspace"));
+        }
+    }
+
+    /**
+     *
+     */
+    private void removeSelectedBootFeatures() {
+        final IStructuredSelection selection = (IStructuredSelection) bootFeaturesViewer.getSelection();
+
+        @SuppressWarnings("unchecked")
+        final Iterator<String> iter = selection.iterator();
+        while (iter.hasNext()) {
+            final String config = iter.next();
+            bootFeaturesList.remove(config);
+            availableFeaturesViewer.setChecked(new AvailableFeature(config, ""), false);
+        }
+
+        bootFeaturesViewer.refresh();
+    }
+}

Added: karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationConstants.java
URL: http://svn.apache.org/viewvc/karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationConstants.java?rev=1227144&view=auto
==============================================================================
--- karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationConstants.java (added)
+++ karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationConstants.java Wed Jan  4 13:22:10 2012
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2009 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;
+
+
+
+
+/**
+ * @author Stephen Evanchik (evanchsa@gmail.com)
+ *
+ */
+public final class KarafLaunchConfigurationConstants {
+
+    /**
+     * The list of features to use during Karaf boot
+     */
+    public static final String KARAF_LAUNCH_BOOT_FEATURES = "karaf_boot_features"; //$NON-NLS-1$
+
+    /**
+     * The workspace project that contains all of the configuration data for the
+     * launch configuration
+     */
+    public static final String KARAF_LAUNCH_CONFIGURATION_PROJECT = "karaf_configuration_project"; //$NON-NLS-1$
+
+    /**
+     * Determines whether or not the Karaf Features system is managed by the
+     * Eclipse launch configuration
+     */
+    public static final String KARAF_LAUNCH_FEATURES_MANAGEMENT = "karaf_features_management"; //$NON-NLS-1$
+
+    /**
+     * PDE Launcher constant used for recording classpath entries used as part
+     * of the boot classpath for Karaf
+     */
+    public static final String KARAF_LAUNCH_REQUIRED_BOOT_CLASSPATH = "karaf_required_boot_classpath"; //$NON-NLS-1$
+
+    /**
+     * Contains the root directory of the Karaf platform that this launch
+     * configuration is configured against
+     */
+    public static final String KARAF_LAUNCH_SOURCE_RUNTIME = "karaf_source_runtime"; //$NON-NLS-1$
+
+    /**
+     * PDE Launcher constant used for determining if the local console should
+     * start
+     */
+    public static final String KARAF_LAUNCH_START_LOCAL_CONSOLE = "karaf_start_local_console"; //$NON-NLS-1$
+
+    /**
+     * PDE Launcher constant used for determining if the remote console should
+     * start
+     */
+    public static final String KARAF_LAUNCH_START_REMOTE_CONSOLE = "karaf_start_remote_console"; //$NON-NLS-1$
+
+    /**
+     * The password used to authenticate to the remote console
+     */
+    public static final String KARAF_REMOTE_CONSOLE_PASSWORD = "karaf_remote_console_password"; //$NON-NLS-1$
+
+    /**
+     * The username used to authenticate to the remote console
+     */
+    public static final String KARAF_REMOTE_CONSOLE_USERNAME = "karaf_remote_console_username"; //$NON-NLS-1$
+
+    /**
+     * Private constructor to prevent instantiation.
+     */
+    private KarafLaunchConfigurationConstants() {
+        throw new AssertionError(KarafLaunchConfigurationConstants.class.getName() + " cannot be instantiated");
+    }
+}

Added: karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationDelegate.java
URL: http://svn.apache.org/viewvc/karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationDelegate.java?rev=1227144&view=auto
==============================================================================
--- karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationDelegate.java (added)
+++ karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationDelegate.java Wed Jan  4 13:22:10 2012
@@ -0,0 +1,518 @@
+/**
+ * Copyright (c) 2009 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
+ *  Timo Naroska - proper console support for Windows
+ */
+package info.evanchik.eclipse.karaf.ui;
+
+import info.evanchik.eclipse.karaf.core.IKarafConstants;
+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.KarafWorkingPlatformModel;
+import info.evanchik.eclipse.karaf.core.PropertyUtils;
+import info.evanchik.eclipse.karaf.core.SystemBundleNames;
+import info.evanchik.eclipse.karaf.core.equinox.BundleEntry;
+import info.evanchik.eclipse.karaf.core.model.WorkingKarafPlatformModel;
+import info.evanchik.eclipse.karaf.ui.internal.WorkbenchServiceExtensions;
+import info.evanchik.eclipse.karaf.ui.workbench.KarafWorkbenchServiceFactory;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMInstall3;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.pde.launching.EquinoxLaunchConfiguration;
+import org.eclipse.pde.launching.IPDELauncherConstants;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author Stephen Evanchik (evanchsa@gmail.com)
+ *
+ */
+public class KarafLaunchConfigurationDelegate extends EquinoxLaunchConfiguration {
+
+    /**
+     * Eclipse Equinox configuration file name
+     */
+    public static final String ECLIPSE_CONFIG_INI_FILE = "config.ini"; //$NON-NLS-1$
+
+    /**
+     * Java Specification Version system property
+     */
+    public static final String JAVA_SPECIFICATION_VERSION = "java.specification.version"; //$NON-NLS-1$
+
+    /**
+     * From the Equinox runtime documentation:<br>
+     * <br>
+     */
+    public static final String OSGI_BUNDLES_KEY = "osgi.bundles"; //$NON-NLS-1$
+
+    /**
+     * The classloader type to use as the parent {@link ClassLoader} of the
+     * context classloader used by the Framework. The valid types are the
+     * following:<br>
+     * <br>
+     * <ul>
+     * <li>app - the application classloader.</li>
+     * <li>boot - the boot classloader.</li>
+     * <li>ext - the extension classloader.</li>
+     * <li>fwk - the framework classloader.</li>
+     * <li>ccl - the original context classloader that was set when the
+     * framework launched (default value).</li>
+     * </ul>
+     */
+    public static final String OSGI_CONTEXT_CLASSLOADER_PARENT_KEY = "osgi.contextClassLoaderParent"; //$NON-NLS-1$
+
+    /**
+     * From the Equinox runtime documentation:<br>
+     * <br>
+     */
+    public static final String OSGI_EXTRA_SYSTEM_PACKAGES_KEY = "org.osgi.framework.system.packages.extra"; //$NON-NLS-1$
+
+    /**
+     * This property is a list of OSGi Framework Extension bundles.
+     */
+    public static final String OSGI_FRAMEWORK_EXTENSION = "osgi.framework.extensions"; //$NON-NLS-1$
+
+    /**
+     * The value used to indicate that the application classloader should be
+     * used as the parent for the Framework.
+     */
+    public static final String OSGI_FRAMEWORK_PARENT_CLASSLOADER_APP = "app"; //$NON-NLS-1$
+
+    /**
+     * From the Equinox runtime documentation:<br>
+     * <br>
+     * The classloader type to use as the parent classloader for the the
+     * Framework. The valid types are the following:<br>
+     * <br>
+     * <ul>
+     * <li>app - the application classloader.</li>
+     * <li>boot - the boot classloader.</li>
+     * <li>ext - the extension classloader.</li>
+     * <li>current - the classloader used to load the Equinox launcher.</li>
+     * </ul>
+     */
+    public static final String OSGI_FRAMEWORK_PARENT_CLASSLOADER_KEY = "osgi.frameworkParentClassloader"; //$NON-NLS-1$
+
+    /**
+     * From the Equinox runtime documentation:<br>
+     * <br>
+     * the install location of the platform. This setting indicates the location
+     * of the basic Eclipse plug-ins and is useful if the Eclipse install is
+     * disjoint. See the section on locations for more details.
+     */
+    public static final String OSGI_INSTALL_AREA_KEY = "osgi.install.area"; //$NON-NLS-1$
+
+    /**
+     * The classloader type to use as the parent {@link ClassLoader} for all
+     * bundles installed in the Framework. The valid types are the following:<br>
+     * <br>
+     * <ul>
+     * <li>app - the application classloader.</li>
+     * <li>boot - the boot classloader.</li>
+     * <li>ext - the extension classloader.</li>
+     * <li>fwk - the framework classloader.</li>
+     * </ul>
+     */
+    public static final String OSGI_PARENT_CLASSLOADER_KEY = "osgi.parentClassloader"; //$NON-NLS-1$
+
+    /**
+     * From the Equinox runtime documentation:<br>
+     * <br>
+     * the start level value the framework will be set to at startup. The
+     * default value is 6.
+     */
+    public static final String OSGI_START_LEVEL_KEY = "osgi.startLevel"; //$NON-NLS-1$
+
+    /**
+     * The source Karaf platform model for this launch configuration
+     */
+    protected KarafPlatformModel karafPlatform;
+
+    /**
+     * This is the working copy of the configured Karaf platform
+     */
+    protected KarafWorkingPlatformModel workingKarafPlatform;
+
+    /**
+     * This is a {@link Map} of the deployed {@link Bundle}s. The key is the
+     * {@code Bundle}'s location the value is its complete entry as parsed from
+     * a {@code config.ini}
+     */
+    private final Map<String, BundleEntry> deployedBundles =
+        new HashMap<String, BundleEntry>();
+
+    /**
+     * Adds the items typically found in {@code KARAF_HOME/lib} as system
+     * classpath entries.<br>
+     * <br>
+     * <b>This requires that
+     * {@link KarafLaunchConfigurationDelegate#OSGI_FRAMEWORK_PARENT_CLASSLOADER_KEY}
+     * be set to "{@code app}"</b>
+     *
+     * @param configuration
+     *            the launch configuration
+     */
+    @Override
+    public String[] getClasspath(final ILaunchConfiguration configuration) throws CoreException {
+        final String[] mainClasspath = super.getClasspath(configuration);
+
+        final List<String> classpath = new ArrayList<String>(Arrays.asList(mainClasspath));
+        final List<String> karafModelClasspath = fixKarafJarClasspathEntry(classpath);
+        classpath.addAll(karafModelClasspath);
+
+        augmentClasspathWithEquinox(classpath);
+
+        return classpath.toArray(new String[0]);
+    }
+
+    @Override
+    public String[] getProgramArguments(final ILaunchConfiguration configuration) throws CoreException {
+        final String[] progArguments = super.getProgramArguments(configuration);
+
+        buildEquinoxConfiguration(configuration);
+
+        final List<String> arguments = new ArrayList<String>();
+
+        for (final String s : progArguments) {
+            arguments.add(s);
+        }
+
+        return arguments.toArray(new String[0]);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     *
+     * @param configuration
+     *            the launch configuration
+     */
+    @Override
+    public String[] getVMArguments(final ILaunchConfiguration configuration) throws CoreException {
+        final String[] vmArguments = super.getVMArguments(configuration);
+
+        final List<String> arguments = new ArrayList<String>();
+        for (final String vmArg : vmArguments) {
+            arguments.add(vmArg);
+        }
+
+        addJavaExtensionsArguments(configuration, arguments);
+
+        final List<KarafWorkbenchServiceFactory> list =
+            WorkbenchServiceExtensions.getLaunchCustomizerFactories();
+
+        for (final KarafWorkbenchServiceFactory f : list) {
+            arguments.addAll(f.getWorkbenchService().getVMArguments(workingKarafPlatform, configuration));
+        }
+
+        return arguments.toArray(new String[0]);
+    }
+
+    /**
+     * {@inheritDoc}<br>
+     * <br>
+     * This will call the proper EIK extension points.
+     */
+    @Override
+    public void launch(final ILaunchConfiguration configuration, final String mode, final ILaunch launch, final IProgressMonitor monitor)
+            throws CoreException {
+        super.launch(configuration, mode, launch, monitor);
+
+        final List<KarafWorkbenchServiceFactory> list =
+            WorkbenchServiceExtensions.getLaunchCustomizerFactories();
+
+        for (final KarafWorkbenchServiceFactory f : list) {
+            f.getWorkbenchService().launch(workingKarafPlatform, configuration, mode, launch, monitor);
+        }
+    }
+
+    @Override
+    protected void preLaunchCheck(final ILaunchConfiguration configuration, final ILaunch launch, final IProgressMonitor monitor) throws CoreException {
+        super.preLaunchCheck(configuration, launch, monitor);
+
+        this.karafPlatform = KarafPlatformModelRegistry.findActivePlatformModel();
+
+        monitor.worked(10);
+
+        final IPath workingArea = new Path(getConfigDir(configuration).getAbsolutePath());
+        workingKarafPlatform = new WorkingKarafPlatformModel(workingArea, karafPlatform);
+
+        monitor.worked(10);
+    }
+
+    /**
+     * Adds the {@code java.endorsed.dirs} and {@code java.ext.dirs} VM
+     * arguments for the Karaf platform
+     *
+     * @param configuration
+     *            the launch configuration
+     * @param arguments
+     *            the current list of arguments
+     * @throws CoreException
+     *             thrown if the {@link VMInstall} cannot be computed
+     */
+    private void addJavaExtensionsArguments(
+            final ILaunchConfiguration configuration,
+            final List<String> arguments) throws CoreException {
+
+        final List<String> endorsedDirs = new ArrayList<String>();
+        endorsedDirs.add(workingKarafPlatform.getParentKarafModel().getRootDirectory().append("lib/endorsed").toString()); //$NON-NLS-1$
+
+        final List<String> extDirs = new ArrayList<String>();
+        extDirs.add(workingKarafPlatform.getParentKarafModel().getRootDirectory().append("lib/ext").toString()); //$NON-NLS-1$
+
+        final IVMInstall vmInstall = JavaRuntime.computeVMInstall(configuration);
+        final File vmRootDirectory = vmInstall.getInstallLocation();
+        if (vmRootDirectory != null) {
+            endorsedDirs.add(new File(vmRootDirectory, "jre/lib/endorsed").getAbsolutePath()); //$NON-NLS-1$
+            endorsedDirs.add(new File(vmRootDirectory, "lib/endorsed").getAbsolutePath()); //$NON-NLS-1$
+
+            extDirs.add(new File(vmRootDirectory, "jre/lib/ext").getAbsolutePath()); //$NON-NLS-1$
+            extDirs.add(new File(vmRootDirectory, "lib/ext").getAbsolutePath()); //$NON-NLS-1$
+        }
+
+        arguments.add(
+                KarafCorePluginUtils.constructSystemProperty(
+                        "java.endorsed.dirs", //$NON-NLS-1$
+                        KarafCorePluginUtils.join(endorsedDirs, File.pathSeparator)));
+
+        arguments.add(
+                KarafCorePluginUtils.constructSystemProperty(
+                        "java.ext.dirs", //$NON-NLS-1$
+                        KarafCorePluginUtils.join(extDirs, File.pathSeparator)));
+    }
+
+    /**
+     * Augment the boot classpath with the Equinox JAR that is running Karaf.
+     * <p>
+     * There is normally an OSGi Framework JAR as a boot classpath item when
+     * Karaf launches. This preserves that behavior.
+     *
+     * @param classpath
+     *            the boot classpath
+     */
+    private void augmentClasspathWithEquinox(final List<String> classpath) {
+        final IPath frameworkPath =
+            new Path(karafPlatform.getState().getBundle(SystemBundleNames.EQUINOX.toString(), null).getLocation());
+
+        classpath.add(frameworkPath.toFile().getAbsolutePath());
+    }
+
+    /**
+     * Construct a config.ini from the Karaf configuration of this launcher.
+     *
+     * @param configuration
+     *            the launch configuration
+     * @throws CoreException
+     *             if there is a problem reading or writing the configuration
+     *             file
+     */
+    private void buildEquinoxConfiguration(final ILaunchConfiguration configuration) throws CoreException {
+
+        final IPath rootDirectory = workingKarafPlatform.getRootDirectory();
+
+        // Load config.ini
+        final Properties equinoxProperties =
+            KarafCorePluginUtils.loadProperties(rootDirectory.toFile(), ECLIPSE_CONFIG_INI_FILE);
+
+        final List<KarafWorkbenchServiceFactory> list =
+            WorkbenchServiceExtensions.getLaunchCustomizerFactories();
+
+        for (final KarafWorkbenchServiceFactory f : list) {
+            final Map<String, String> m =
+                f.getWorkbenchService().getAdditionalEquinoxConfiguration(workingKarafPlatform, configuration);
+
+            equinoxProperties.putAll(m);
+        }
+
+        final String currentBundles =
+            (String) equinoxProperties.get(OSGI_BUNDLES_KEY);
+
+        final String allBundles = mergeDeployedBundles(currentBundles, configuration);
+
+        equinoxProperties.put(OSGI_BUNDLES_KEY, allBundles);
+
+        /*
+         * Set the following OSGi / Equinox properties:
+         */
+        if (!equinoxProperties.containsKey(OSGI_START_LEVEL_KEY)) {
+	        final Integer defaultStartLevel =
+	            configuration.getAttribute(
+	                    IPDELauncherConstants.DEFAULT_START_LEVEL,
+	                    new Integer(IKarafConstants.KARAF_DEFAULT_BUNDLE_START_LEVEL));
+
+	        equinoxProperties.put(OSGI_START_LEVEL_KEY, defaultStartLevel.toString());
+        }
+
+        /*
+         * Set the osgi.install.area to the runtime plugins directory or the
+         * directory containing Equinox?
+         *
+         * "/org/eclipse/osgi/3.5.0.v20090429-1630"
+         */
+        final IPath frameworkPath =
+            new Path(karafPlatform.getState().getBundle(SystemBundleNames.EQUINOX.toString(), null).getLocation());
+        equinoxProperties.put(OSGI_INSTALL_AREA_KEY, frameworkPath.removeLastSegments(1).toString());
+
+        final String javaSpecificationVersion = getJavaRuntimeSpecificationVersion(configuration);
+        equinoxProperties.put(JAVA_SPECIFICATION_VERSION, javaSpecificationVersion);
+
+        /*
+         * This is very important as it allows the boot classpath entries to
+         * present their classes to the framework. Without it NoClassDefFound
+         * shows up for classes like org.apache.karaf.jaas.boot.ProxyLoginModule
+         */
+        equinoxProperties.put(OSGI_FRAMEWORK_PARENT_CLASSLOADER_KEY, OSGI_FRAMEWORK_PARENT_CLASSLOADER_APP);
+        equinoxProperties.put(OSGI_CONTEXT_CLASSLOADER_PARENT_KEY, OSGI_FRAMEWORK_PARENT_CLASSLOADER_APP);
+        equinoxProperties.put(OSGI_PARENT_CLASSLOADER_KEY, OSGI_FRAMEWORK_PARENT_CLASSLOADER_APP);
+
+        /*
+         * Eclipse 3.7 (Indigo) has a bug that does not ignore the empty
+         * org.osgi.framework.system.packages.extra property
+         */
+        final String extraSystemPackages = (String) equinoxProperties.get(OSGI_EXTRA_SYSTEM_PACKAGES_KEY);
+        if (extraSystemPackages.trim().isEmpty()) {
+            equinoxProperties.remove(OSGI_EXTRA_SYSTEM_PACKAGES_KEY);
+        }
+
+        PropertyUtils.interpolateVariables(equinoxProperties, equinoxProperties);
+
+        KarafCorePluginUtils.save(new File(getConfigDir(configuration), ECLIPSE_CONFIG_INI_FILE), equinoxProperties);
+    }
+
+    /**
+     * Fixes the {@code karaf.jar} classpath entry so that it is compatible with
+     * all versions of Eclipse.
+     * <p>
+     * This JAR ordinarily contains classes in the {@code org/osgi} package.
+     * These classes conflict with Eclipse Indigo (3.7) and later versions of
+     * the same classes found in the org.eclipse.osgi bundle.
+     *
+     * @param classpath
+     *            the list of classpath entries to process
+     * @return the list of classpath entries after being fixed to work in all
+     *         versions of Eclipse
+     * @throws CoreException
+     *             if there is a problem fixing the classpath
+     */
+    private List<String> fixKarafJarClasspathEntry(final List<String> classpath)
+            throws CoreException
+    {
+        final List<String> karafModelClasspath = karafPlatform.getBootClasspath();
+
+        File karafJar = null;
+        File filteredKarafJar = null;
+
+        final Iterator<String> itr = karafModelClasspath.iterator();
+        while (itr.hasNext()) {
+            final String classpathEntry = itr.next();
+            karafJar = new File(classpathEntry);
+            if (!karafJar.getName().equalsIgnoreCase("karaf.jar")) {
+                continue;
+            }
+
+            itr.remove();
+
+            // TODO: This should be factored out somehow
+            final IKarafProject karafProject = (IKarafProject) karafPlatform.getAdapter(IKarafProject.class);
+            final IFile file = karafProject.getFile(".bin/runtime/generatedKaraf.jar");
+            final IPath path = file.getRawLocation();
+            filteredKarafJar = path.toFile();
+        }
+
+        if (filteredKarafJar != null) {
+            classpath.add(filteredKarafJar.getAbsolutePath());
+        } else {
+            classpath.add(karafJar.getAbsolutePath());
+        }
+        return karafModelClasspath;
+    }
+
+    /**
+     * Determines the Java Specification Version of the Java Virtual Machine
+     * that will execute Karaf. If the {@link VMInstall} does not support
+     * evaluating system properties then the workbench's specification version
+     * is used.
+     *
+     * @param configuration
+     *            the launch configuration
+     * @return the Java Specification Version (e.g "1.6" or "1.5")
+     * @throws CoreException
+     *             if there is a problem determining the Java Specification
+     *             Version of the {@code VMInstall}
+     */
+    private String getJavaRuntimeSpecificationVersion(final ILaunchConfiguration configuration) throws CoreException {
+        final IVMInstall vmInstall = JavaRuntime.computeVMInstall(configuration);
+        if (!(vmInstall instanceof IVMInstall3)) {
+            return System.getProperty(JAVA_SPECIFICATION_VERSION);
+        }
+
+        final IVMInstall3 vmInstall3 = (IVMInstall3) vmInstall;
+
+        @SuppressWarnings("unchecked")
+        final Map<String, String> properties =
+            vmInstall3.evaluateSystemProperties(new String[] { JAVA_SPECIFICATION_VERSION }, new NullProgressMonitor());
+
+        return properties.get(JAVA_SPECIFICATION_VERSION);
+    }
+
+    /**
+     *
+     * @param currentBundles
+     * @param configuration
+     * @return
+     */
+    private String mergeDeployedBundles(final String currentBundles, final ILaunchConfiguration configuration) throws CoreException {
+
+        /*
+         * Create a Map of all the bundles that we are going to deploy in this
+         * launch of the Karaf
+         */
+        deployedBundles.clear();
+
+        final List<BundleEntry> bundles = KarafCorePluginUtils.getEquinoxBundles(currentBundles);
+        for(final BundleEntry b : bundles) {
+            deployedBundles.put(b.getBundle(), b);
+        }
+
+        final List<KarafWorkbenchServiceFactory> list =
+            WorkbenchServiceExtensions.getLaunchCustomizerFactories();
+
+        for (final KarafWorkbenchServiceFactory f : list) {
+            final List<BundleEntry> extBundles =
+                f.getWorkbenchService().getAdditionalBundles(workingKarafPlatform, configuration);
+
+            for(final BundleEntry b : extBundles) {
+                if(!deployedBundles.containsKey(b.getBundle())) {
+                    deployedBundles.put(b.getBundle(), b);
+                }
+            }
+        }
+
+        return KarafCorePluginUtils.join(deployedBundles.values(), ",");  //$NON-NLS-1$
+    }
+}

Added: karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationInitializer.java
URL: http://svn.apache.org/viewvc/karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationInitializer.java?rev=1227144&view=auto
==============================================================================
--- karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationInitializer.java (added)
+++ karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafLaunchConfigurationInitializer.java Wed Jan  4 13:22:10 2012
@@ -0,0 +1,270 @@
+/**
+ * Copyright (c) 2009 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.IKarafConstants;
+import info.evanchik.eclipse.karaf.core.KarafCorePluginUtils;
+import info.evanchik.eclipse.karaf.core.KarafPlatformModel;
+import info.evanchik.eclipse.karaf.core.KarafPlatformModelFactory;
+import info.evanchik.eclipse.karaf.core.KarafPlatformModelRegistry;
+import info.evanchik.eclipse.karaf.core.SystemBundleNames;
+import info.evanchik.eclipse.karaf.core.configuration.StartupSection;
+import info.evanchik.eclipse.karaf.core.equinox.BundleEntry;
+import info.evanchik.eclipse.karaf.core.model.WorkingKarafPlatformModel;
+import info.evanchik.eclipse.karaf.ui.internal.WorkbenchServiceExtensions;
+import info.evanchik.eclipse.karaf.ui.workbench.KarafWorkbenchServiceFactory;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.pde.core.plugin.IPluginBase;
+import org.eclipse.pde.core.plugin.IPluginModelBase;
+import org.eclipse.pde.core.plugin.ModelEntry;
+import org.eclipse.pde.core.plugin.PluginRegistry;
+import org.eclipse.pde.internal.launching.launcher.LaunchConfigurationHelper;
+import org.eclipse.pde.internal.ui.IPDEUIConstants;
+import org.eclipse.pde.launching.IPDELauncherConstants;
+import org.eclipse.pde.launching.OSGiLaunchConfigurationInitializer;
+import org.osgi.framework.Version;
+
+/**
+ * @author Stephen Evanchik (evanchsa@gmail.com)
+ *
+ */
+@SuppressWarnings("restriction")
+public class KarafLaunchConfigurationInitializer extends OSGiLaunchConfigurationInitializer {
+
+    public static final char VERSION_SEPARATOR = '*';
+
+    /**
+     * Convenience method for initializing a Karaf launch configuration
+     *
+     * @param configuration
+     *            the working copy of the launch configuration
+     */
+    public static void initializeConfiguration(final ILaunchConfigurationWorkingCopy configuration) {
+        final KarafLaunchConfigurationInitializer configurationInitializer = new KarafLaunchConfigurationInitializer();
+        configurationInitializer.initialize(configuration);
+    }
+
+    /**
+     * The model that represents the Karaf platform
+     */
+    protected KarafPlatformModel karafPlatform;
+
+    protected KarafPlatformModelFactory karafPlatformFactory;
+
+    protected StartupSection startupSection;
+
+    @Override
+    public void initialize(final ILaunchConfigurationWorkingCopy configuration) {
+        loadKarafPlatform(configuration);
+
+        final File configDir =
+            LaunchConfigurationHelper.getConfigurationArea(configuration);
+
+        final IPath workingArea = new Path(configDir.getAbsolutePath());
+        final WorkingKarafPlatformModel workingKarafPlatform =
+            new WorkingKarafPlatformModel(workingArea, karafPlatform);
+
+        workingKarafPlatform.getConfigurationDirectory().toFile().mkdirs();
+        workingKarafPlatform.getUserDeployedDirectory().toFile().mkdirs();
+
+        // TODO: Factor this out so that it pulls the ID from this plugins
+        // registry
+        configuration.setAttribute(IPDELauncherConstants.OSGI_FRAMEWORK_ID, "info.evanchik.eclipse.karaf.Framework"); //$NON-NLS-1$
+        configuration.setAttribute(IPDEUIConstants.LAUNCHER_PDE_VERSION, "3.3"); //$NON-NLS-1$
+
+        configuration.setAttribute(KarafLaunchConfigurationConstants.KARAF_LAUNCH_SOURCE_RUNTIME, karafPlatform.getRootDirectory().toOSString());
+
+        addDefaultVMArguments(configuration);
+
+        try {
+            final List<KarafWorkbenchServiceFactory> list = WorkbenchServiceExtensions.getLaunchCustomizerFactories();
+
+            for (final KarafWorkbenchServiceFactory f : list) {
+                f.getWorkbenchService().initialize(workingKarafPlatform, configuration);
+            }
+        } catch (final CoreException e) {
+            KarafUIPluginActivator.getLogger().error("Unable to access extension registry", e);
+        }
+
+        // This must be the last item called
+        super.initialize(configuration);
+    }
+
+    /**
+     * Initializes the auto start property to true for the bundles found in the
+     * Karaf platform and defers the the parent for all other bundles.
+     *
+     * @see org.eclipse.pde.ui.launcher.OSGiLaunchConfigurationInitializer#getAutoStart
+     *      (java.lang.String)
+     */
+    @Override
+    protected String getAutoStart(final String bundleID) {
+        if (startupSection.containsPlugin(bundleID)) {
+            return "true"; //$NON-NLS-1$
+        } else {
+            return super.getAutoStart(bundleID);
+        }
+    }
+
+    /**
+     * Initializes the bundles associated with the Karaf platform with the
+     * correct default start levels and falls back to the default start level
+     * provided by the parent.
+     *
+     * @see org.eclipse.pde.ui.launcher.OSGiLaunchConfigurationInitializer#getStartLevel
+     *      (java.lang.String)
+     */
+    @Override
+    protected String getStartLevel(final String bundleID) {
+        if (startupSection.containsPlugin(bundleID)) {
+            return startupSection.getStartLevel(bundleID);
+        } else {
+            return super.getStartLevel(bundleID);
+        }
+    }
+
+    @Override
+    protected void initializeBundleState(final ILaunchConfigurationWorkingCopy configuration) {
+        super.initializeBundleState(configuration);
+
+        final List<String> externalPlugins = new ArrayList<String>();
+        final List<String> workspacePlugins = new ArrayList<String>();
+
+        final IPluginModelBase[] models = PluginRegistry.getActiveModels();
+        for (int i = 0; i < models.length; i++) {
+            final String id = models[i].getPluginBase().getId();
+
+            // Skip the Felix OSGi Framework
+            if (SystemBundleNames.FELIX.toString().equals(id)) {
+                continue;
+            }
+
+            final BundleEntry entry = new BundleEntry.Builder(getBundleId(models[i])).autostart(getAutoStart(id)).startLevel(
+                    getStartLevel(id)).build();
+
+            final boolean inWorkspace = models[i].getUnderlyingResource() != null;
+            if (inWorkspace) {
+                workspacePlugins.add(entry.toString());
+            } else {
+                // By default, only add the plugin if it is in the Karaf model
+                final Version v = Version.parseVersion(models[i].getPluginBase().getVersion());
+                if (karafPlatform.getState().getBundle(id, v) != null && startupSection.containsPlugin(id)) {
+                    externalPlugins.add(entry.toString());
+                }
+            }
+        }
+
+        configuration.setAttribute(IPDELauncherConstants.WORKSPACE_BUNDLES, KarafCorePluginUtils.join(workspacePlugins, ","));
+        configuration.setAttribute(IPDELauncherConstants.TARGET_BUNDLES, KarafCorePluginUtils.join(externalPlugins, ","));
+        configuration.setAttribute(IPDELauncherConstants.AUTOMATIC_ADD, true);
+        configuration.setAttribute(IPDELauncherConstants.SHOW_SELECTED_ONLY, true);
+    }
+
+    /**
+     * Initializes a series of default configuration items for the framework
+     * launcher. This includes registering the default boot classpath entries
+     * and setting the Karaf platform default OSGi bundle start level.
+     *
+     * @param configuration
+     *            the launch configuration
+     * @see org.eclipse.pde.ui.launcher.OSGiLaunchConfigurationInitializer#initializeFrameworkDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+     */
+    @Override
+    protected void initializeFrameworkDefaults(final ILaunchConfigurationWorkingCopy configuration) {
+        final List<String> bootClasspathEntries = karafPlatform.getBootClasspath();
+
+        final String bootClasspath = KarafCorePluginUtils.join(bootClasspathEntries, ",");
+
+        configuration.setAttribute(
+                KarafLaunchConfigurationConstants.KARAF_LAUNCH_REQUIRED_BOOT_CLASSPATH,
+                bootClasspath);
+
+        configuration.setAttribute(
+                IPDELauncherConstants.DEFAULT_START_LEVEL,
+                Integer.parseInt(IKarafConstants.KARAF_DEFAULT_BUNDLE_START_LEVEL));
+    }
+
+    /**
+     * Loads a Karaf platform definition based on the context of the launch
+     * configuration.
+     *
+     * @param configuration
+     */
+    protected void loadKarafPlatform(final ILaunchConfigurationWorkingCopy configuration) {
+        try {
+            this.karafPlatform = KarafPlatformModelRegistry.findActivePlatformModel();
+            this.karafPlatformFactory = KarafPlatformModelRegistry.findPlatformModelFactory(karafPlatform.getRootDirectory());
+
+            this.startupSection = (StartupSection) this.karafPlatform.getAdapter(StartupSection.class);
+            this.startupSection.load();
+        } catch (final CoreException e) {
+            KarafUIPluginActivator.getLogger().error("Unable to locate the Karaf platform", e);
+
+            this.karafPlatform = null;
+        }
+    }
+
+    /**
+     * Returns the a plugin id favoring the newest version in the target
+     * platform
+     *
+     * @param model
+     *            the {@link IPluginModelBase}
+     * @return the string plugin identifier with an optional version set at the
+     *         newest version if there is more than one plugin that responds to
+     *         the given id
+     */
+    private String getBundleId(final IPluginModelBase model) {
+        final IPluginBase base = model.getPluginBase();
+        final String id = base.getId();
+        final StringBuffer buffer = new StringBuffer(id);
+
+        final ModelEntry entry = PluginRegistry.findEntry(id);
+        if (entry.getActiveModels().length > 1) {
+            buffer.append(VERSION_SEPARATOR);
+            buffer.append(model.getPluginBase().getVersion());
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * Adds default VM arguments to this launch configuration
+     *
+     * @param configuration
+     *            the working copy of the launch configuration
+     */
+    private void addDefaultVMArguments(final ILaunchConfigurationWorkingCopy configuration) {
+        final StringBuffer vmArgs = new StringBuffer();
+
+        if (vmArgs.indexOf("-Dosgi.noShutdown") == -1) { //$NON-NLS-1$
+            vmArgs.append(" -Dosgi.noShutdown=true"); //$NON-NLS-1$
+        }
+
+        // prevent terminal CTRL-characters in Eclipse console on Windows
+        final String localOperatingSystem = System.getProperty("os.name"); //$NON-NLS-1$
+        if (   localOperatingSystem.toLowerCase().indexOf("windows") >= 0 //$NON-NLS-1$
+            && vmArgs.indexOf("-Djline.terminal") == -1) { //$NON-NLS-1$
+            vmArgs.append(" -Djline.terminal=jline.UnsupportedTerminal"); //$NON-NLS-1$
+        }
+
+        configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs.toString());
+    }
+}

Added: karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafUIPluginActivator.java
URL: http://svn.apache.org/viewvc/karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafUIPluginActivator.java?rev=1227144&view=auto
==============================================================================
--- karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafUIPluginActivator.java (added)
+++ karaf/eik/trunk/plugins/info.evanchik.eclipse.karaf.ui/src/main/java/info/evanchik/eclipse/karaf/ui/KarafUIPluginActivator.java Wed Jan  4 13:22:10 2012
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2009 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.LogWrapper;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class KarafUIPluginActivator extends AbstractUIPlugin {
+
+    // The plug-in ID
+    public static final String PLUGIN_ID = "info.evanchik.eclipse.karaf.ui"; // $NON-NLS-1$
+
+    public static final String BUNDLE_OBJ_IMG = "bundle_obj"; //$NON-NLS-1$
+
+    public static final String FEATURE_OBJ_IBM = "feature_obj"; //$NON-NLS-1$
+
+    public static final String LOGO_16X16_IMG = "logo16"; //$NON-NLS-1$
+
+    public static final String LOGO_32X32_IMG = "logo32"; //$NON-NLS-1$
+
+    public static final String LOGO_64X64_IMG = "logo64"; //$NON-NLS-1$
+
+    // The shared instance
+    private static KarafUIPluginActivator plugin;
+
+    private BundleContext bundleContext;
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static KarafUIPluginActivator getDefault() {
+        return plugin;
+    }
+
+    /**
+     * Getter for the {@link LogWrapper} object that makes logging much easier
+     * on the caller.
+     *
+     * @return the {@link LogWrapper} instance
+     */
+    public static LogWrapper getLogger() {
+        return new LogWrapper(getDefault().getLog(), PLUGIN_ID);
+    }
+
+    /**
+     * The constructor
+     */
+    public KarafUIPluginActivator() {
+        super();
+    }
+
+    /**
+     * Returns a service with the specified name or {@code null} if none.
+     *
+     * @param serviceName
+     *            name of service
+     * @return service object or {@code null} if none
+     */
+    public Object getService(final String serviceName) {
+        final ServiceReference reference = bundleContext.getServiceReference(serviceName);
+        if (reference == null) {
+            return null;
+        }
+
+        final Object service = bundleContext.getService(reference);
+        if (service != null) {
+            bundleContext.ungetService(reference);
+        }
+
+        return service;
+    }
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        super.start(context);
+        plugin = this;
+        bundleContext = context;
+    }
+
+    @Override
+    public void stop(final BundleContext context) throws Exception {
+        plugin = null;
+        bundleContext = null;
+
+        super.stop(context);
+    }
+
+    /**
+     * Creates the {@link ImageRegistery} for this plugin. Images can be
+     * retrieved using the static accessor method
+     * {@link KarafUIPluginActivator#getImageDescriptor(String)}
+     *
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#createImageRegistry()
+     */
+    @Override
+    protected void initializeImageRegistry(final ImageRegistry imageRegistry) {
+        registerImage(imageRegistry, BUNDLE_OBJ_IMG, "icons/obj16/bundle_obj.gif"); //$NON-NLS-1$
+        registerImage(imageRegistry, FEATURE_OBJ_IBM, "icons/obj16/feature_obj.gif"); //$NON-NLS-1$
+        registerImage(imageRegistry, "runtime_obj", "icons/obj16/runtime_obj.gif"); //$NON-NLS-1$
+        registerImage(imageRegistry, "details_view", "icons/obj16/details_view.gif"); //$NON-NLS-1$
+        registerImage(imageRegistry, LOGO_16X16_IMG, "icons/obj16/karaf-logo-16x16.png"); //$NON-NLS-1$
+        registerImage(imageRegistry, LOGO_32X32_IMG, "icons/obj32/karaf-logo-32x32.png"); //$NON-NLS-1$
+        registerImage(imageRegistry, LOGO_64X64_IMG, "icons/obj64/karaf-logo-64x64.png"); //$NON-NLS-1$
+    }
+
+    /**
+     * Registers an {@link ImageDescriptor} with the {@link ImageRegistry}
+     *
+     * @param registry
+     *            the instance of {@link ImageRegistry}
+     * @param key
+     *            the key to register the image under
+     * @param imageUrl
+     *            the URL, relative to the {@link ICON_ROOT_URL}, of the image
+     *            to be registered
+     */
+    private void registerImage(final ImageRegistry registry, final String key, final String imageUrl) {
+        final ImageDescriptor id = imageDescriptorFromPlugin(PLUGIN_ID, imageUrl);
+        registry.put(key, id);
+    }
+}