Package au.com.forge.felix.eclipse_pde_launcher.impl

Source Code of au.com.forge.felix.eclipse_pde_launcher.impl.EclipsePDEFelixLauncher

/**
*  Eclipse PDE Felix Launcher - launches Apache Felix with support for Eclipse PDE project
*  directories as bundles
*  Copyright (C) 2010 Forge Research
*  Copyright (C) 2010-2014 Christopher Armstrong <carmstrong@fastmail.com.au>
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*/
package au.com.forge.felix.eclipse_pde_launcher.impl;

import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.felix.framework.Felix;
import org.apache.felix.framework.FrameworkFactory;
import org.apache.felix.framework.util.StringMap;
import org.apache.felix.main.AutoProcessor;
import org.apache.felix.main.Main;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleException;

import au.com.forge.eclipse.osgi.autoupdater.impl.EclipseProjectURLAutoUpdater;
import au.com.forge.eclipse.osgi.urlhandler.impl.EPURLHandlerActivator;

/**
* The Eclipse PDE Felix framework launcher. It automatically installs the
* Eclipse project directory stream handler and the Eclipse project URL
* auto-updater.
*
* It is needed to be able to start the Apache Felix framework from an Eclipse
* launch configuration that specifies startup bundles.
*
*
* @author Christopher Armstrong
*
*/
public class EclipsePDEFelixLauncher {
  private static Felix framework = null;
 
  /**
   * Internal launcher property specifying the path to
   * the configuration file.
   */
  private static final String LAUNCHER_CONFIG_PROPERTY_KEY = "au.com.forge.felix.config.properties";

  /**
     * Internal launcher property specifying if the user
     * selected to initialise AWT on MacOS X.
     *
     * @author MOD_0.2.2 ogattaz
     * */
    private static final String LAUNCHER_INIT_AWT_KEY = "au.com.forge.felix.config.init.awt";

  /**
   * Launch the Felix instance.
   *
   * @param args
   */
  public static void main(String[] args) {
    Main.loadSystemProperties();
    Map<String, String> configProperties = Main.loadConfigProperties();
    if (configProperties == null) {
      configProperties = new HashMap<String, String>();
    }
    Main.copySystemProperties(configProperties);

    mergeWithPDELauncherProperties(configProperties);

    String enableHook = configProperties
        .get(Main.SHUTDOWN_HOOK_PROP);
    if (enableHook == null || !enableHook.equalsIgnoreCase("false")) {
      Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
          try {
            framework.stop();
            framework.waitForStop(0);
          } catch (Exception e) {
            System.err.println("Error stopping framework: " + e);
            e.printStackTrace(System.err);
          }
        }
      });
    }
   
        /*
         * MOD_0.2.2 ogattaz
         *
         * Load the awt native library AWT (mapped on top of cocoa) if the
         * property "au.com.forge.felix.config.initawtinmain" contains "true" and
         * if the current OS is "OS X" and the current thread is the main thread
         * of the jvm
         */
        if (mustInitAwt(configProperties)) {
            initAwt(configProperties);
        }

    try {
      FrameworkFactory frameworkFactory = getFrameworkFactory();
      ArrayList<BundleActivator> activators = new ArrayList<BundleActivator>();

      // Must put the URL handler first because it is used during
      // the auto-update process.
      activators.add(new EPURLHandlerActivator());
      activators.add(new EclipseProjectURLAutoUpdater());

      StringMap stringMap = new StringMap(configProperties);
      stringMap.put("felix.systembundle.activators", activators);

      framework = (Felix)frameworkFactory.newFramework(stringMap);
      framework.init();
      AutoProcessor.process(stringMap, framework.getBundleContext());
      framework.start();
      framework.waitForStop(0);
      System.exit(0);
    } catch (BundleException e) {
      System.err.println("Could not start the framework framework: " + e);
      e.printStackTrace();
      System.exit(1);
    } catch (InterruptedException e) {
      System.err.println("Interrupted waiting for framework to finish: "
          + e);
      e.printStackTrace();
      System.exit(1);
    }
  }

  private static FrameworkFactory getFrameworkFactory() {
    return new org.apache.felix.framework.FrameworkFactory();
  }

  /**
   * Load the custom properties from {@link #LAUNCHER_CONFIG_PROPERTY_KEY} file
   * and merge them into the Felix properties.
   *
   * @param configProperties felix properties
   */
  private static void mergeWithPDELauncherProperties(
      Map<String, String> configProperties) {
    String configUri = System.getProperty(LAUNCHER_CONFIG_PROPERTY_KEY);

    if (configUri == null) {
      // nothing todo
      return;
    }
    try {
      InputStream openStream = URI.create(configUri).toURL().openStream();
      Properties toMergeProperties = new Properties();
      toMergeProperties.load(openStream);
      Enumeration<Object> keys = toMergeProperties.keys();
      while (keys.hasMoreElements()) {
        String key = (String) keys.nextElement();

        if (key.startsWith("felix.auto.")) {
          configProperties.put(
              key,
              mergeFelixBundleAutoOrInstallString(
                  (String) configProperties.get(key),
                  (String) toMergeProperties.get(key)));

        } else {
          configProperties.put(key, toMergeProperties.getProperty(key));
        }
      }

    } catch (IOException e) {
      System.err
          .println("error while loading PDE felix configuration file: "
              + e);
      e.printStackTrace();
      // ?!
      // System.exit(1);
    }
  }

  /**
   * Combine a Felix bundle list string with another
   *
   * @param toBeExtended the bundle list to be extended (may be null)
   * @param toExtend the bundle list to append
   * @return the combined string
   */
  private static String mergeFelixBundleAutoOrInstallString(
      String toBeExtended, String toExtend) {

    StringBuilder builder = new StringBuilder();
    if (toBeExtended != null) {
      builder.append(toBeExtended);
      builder.append(" ");
    }
    builder.append(toExtend);
    return builder.toString();
  }
 
    /**
     * Induce AWT initialisation.
     * @author MOD_0.2.2 ogattaz
     *
     * @param configProperties
     */
    private static void initAwt(Map<String, String> configProperties) {

            try {
                    int wRgbInt = Color.BLUE.getRGB();
                    System.out.println(String
                        .format("EclipsePDEFelixLauncher initializes AWT in Thread [%s] OK : Color.BLUE.getRGB=[%s]",
                                               Thread.currentThread().getName(),
                                               Integer.toHexString(wRgbInt)));
            } catch (Exception e) {
                    // if the jvm is an headless one ...
                    System.err
                                    .println(String
                                                    .format("EclipsePDEFelixLauncher thrown an exception during AWT initialisation : %s",
                                                                    e.getMessage()));
                   
                    e.printStackTrace(System.err);
            }
    }

    /**
     * Determine if AWT must be initialised based on the {@link #LAUNCHER_INIT_AWT_KEY}
     * and the operating system.
     *
     * MOD_0.2.2 ogattaz
     *
     * the name of the property :"au.com.forge.felix.config.init.awt"
     *
     *
     * @param configProperties
     *            the map of the properties given to the launcher
     * @return true is the initialisation of awt is explicitly asked of if the
     *         current OS is "OS X" and if the current Thread is the "main" one.
     */
    private static boolean mustInitAwt(Map<String, String> configProperties) {

            String launchAwtProperty = configProperties.get(LAUNCHER_INIT_AWT_KEY);

            if (launchAwtProperty != null) {
                    // Check the property value, and return true only if
                    // the user has set the property to true AND it is the main thread
                    // AND MacOSX
                    boolean wExplicitInitAwt = Boolean.parseBoolean(launchAwtProperty);

                    return wExplicitInitAwt && isMacOsX() && isThreadmain();
            } else {
                    // The user has not set the property, so initialise AWT
                    // if we are running MacOS X and this is the main thread
                    return isMacOsX() && isThreadmain();
            }
    }

    /**
     * Determine if the current thread is also the main thread
     *
     * MOD_0.2.2 ogattaz
     *
     * Thread.currentThread().getName() => name=[main]
     *
     * @return true if the name of the current Thread is "main"
     */
    private static boolean isThreadmain() {
            return "main".equals(Thread.currentThread().getName());
    }

    /**
     * MOD_0.2.2 ogattaz
     *
     * System property "os.name" contains : OsName=[Mac OS X]
     *
     * @see "Identifying OS X from Java" =>
     *      https://developer.apple.com/library/mac/technotes/tn2002/tn2110.html
     *
     * @return
     */
    private static boolean isMacOsX() {

            String wOsName = getOsName();
            return (wOsName != null && !wOsName.isEmpty()) ? wOsName.toUpperCase()
                            .contains("OS X") : false;
    }

    /**
     * MOD_0.2.2 ogattaz
     *
     * @return the value of the System property "os.name"
     */
    public static String getOsName() {
            return System.getProperty("os.name");
    }
}
TOP

Related Classes of au.com.forge.felix.eclipse_pde_launcher.impl.EclipsePDEFelixLauncher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.