net.rim.ejde.internal.util.VMUtils.java Source code

Java tutorial

Introduction

Here is the source code for net.rim.ejde.internal.util.VMUtils.java

Source

/*
* Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License, Version 1.0,
* which accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
*/
package net.rim.ejde.internal.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

import net.rim.ejde.internal.core.ContextManager;
import net.rim.ejde.internal.core.IConstants;
import net.rim.ejde.internal.model.BlackBerrySDKInstall;
import net.rim.ejde.internal.model.BlackBerryVMInstallType;
import net.rim.ejde.internal.model.preferences.WarningsPreferences;
import net.rim.ejde.internal.signing.BBSigningKeys;
import net.rim.ejde.internal.sourcelookup.RIMClasspathProvider;
import net.rim.ide.RIA;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.internal.launching.LaunchingMessages;
import org.eclipse.jdt.launching.AbstractVMInstall;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.VMStandin;
import org.eclipse.jdt.launching.environments.ExecutionEnvironmentDescription;
import org.osgi.framework.Version;

/**
 * The Class VMUtils.
 *
 * @author cmalinescu, jheifetz, rgunartanam
 */
public class VMUtils {
    static private final Logger _log = Logger.getLogger(VMUtils.class);
    private static Map<String, BBSigningKeys> _signKeysCache = new HashMap<String, BBSigningKeys>();

    /**
     * Gets the sign keys cache.
     *
     * @return the sign keys cache
     */
    public static Map<String, BBSigningKeys> getSignKeysCache() {
        return _signKeysCache;
    }

    /**
     * Adds the sign keys to cache.
     *
     * @param vm
     *            the vm
     *
     * @return the bB signing keys
     */
    public static BBSigningKeys addSignKeysToCache(IVMInstall vm) {
        if (vm == null) { // This could happen in import failed due to a bug
            _log.error("No BlackBerry VM found and Signing Keys cache cannot be populated.");
            return null;
        }
        String vmName = vm.getName();
        if (!_signKeysCache.containsKey(vmName)) {
            RIA ria = ContextManager.PLUGIN.getRIA(vm.getInstallLocation().getPath());
            BBSigningKeys signingKeys = new BBSigningKeys(ria);
            _signKeysCache.put(vmName, signingKeys);
            _log.debug("SigningKey cache is populated for vm: " + vmName);
            return signingKeys;
        }
        return _signKeysCache.get(vmName);
    }

    /**
     * Removes the sign keys from cache.
     *
     * @param vm
     *            the vm
     */
    public static void removeSignKeysFromCache(IVMInstall vm) {
        if (vm == null) { // This could happen in import failed due to a bug
            _log.error("No BlackBerry VM found and Signing Keys cache cannot be populated.");
            return;
        }
        if (_signKeysCache.containsKey(vm.getName())) {
            _signKeysCache.remove(vm.getName());
            _log.debug("SigningKey object for " + vm.getName() + " is removed from the cache.");
        }
    }

    /**
     * Convert key to preference label.
     *
     * @param keyId
     *            the key id
     * @param vmName
     *            the vm name
     *
     * @return the string
     */
    public static String convertKeyToPreferenceLabel(Integer keyId, String vmName) {
        String id = null;
        if ((vmName != null)) {
            BBSigningKeys keyCache = VMUtils.getSignKeysCache().get(vmName);
            return VMUtils.convertKeyToPreferenceLabel(keyId, keyCache);
        }
        return id;
    }

    /**
     * Convert key to preference label.
     *
     * @param keyId
     *            the key id
     * @param keyCache
     *            the key cache
     *
     * @return the string
     */
    public static String convertKeyToPreferenceLabel(Integer keyId, BBSigningKeys keyCache) {
        String id = null;
        if ((keyId != null) && (keyCache != null)) {
            id = ((keyCache.getKeyName(keyId) != null) ? keyCache.getKeyName(keyId).trim() : "") + " (0x" //$NON-NLS-1$//$NON-NLS-2$
                    + Integer.toHexString(keyId.intValue()) + ")";//$NON-NLS-1$
        }
        return id;
    }

    /**
     * Convert preference label to key.
     *
     * @param preferenceLabel
     *            the preference label
     *
     * @return the integer
     */
    public static Integer convertPreferenceLabelToKey(String preferenceLabel) {
        int begin = preferenceLabel.indexOf("(0x");
        int end = preferenceLabel.indexOf(')');
        return Integer.valueOf(Integer.parseInt(preferenceLabel.substring(begin + 3, end), 16));
    }

    /**
     * Convert code sign error msg to preference label.
     *
     * @param msg
     *            the msg
     *
     * @return the string
     */
    public static String convertCodeSignErrorMsgToPreferenceLabel(String msg) {
        int indexA = msg.indexOf(":");
        String keyLabel = msg.substring(indexA + 1);
        int indexB = keyLabel.indexOf(":");
        return keyLabel.substring(0, indexB).trim();
    }

    /**
     * Gets the hidden classes filtered by preferences.
     *
     * @param vmName
     *            the vm name
     *
     * @return the hidden classes filtered by preferences
     */
    public static List<String> getHiddenClassesFilteredByPreferences(String vmName) {
        List<String> hiddenClasses = new ArrayList<String>();
        if ((_signKeysCache != null) && (vmName != null) && _signKeysCache.containsKey(vmName)) {
            BBSigningKeys keyCache = _signKeysCache.get(vmName);
            // These must be generated through addition, as keyCache.getProtectedClasses() contains classes
            // not associated with any of the desired keys.
            for (int key : keyCache.getKeys()) {
                Integer iKey = Integer.valueOf(key);
                if (!WarningsPreferences.getWarnStatus(VMUtils.convertKeyToPreferenceLabel(iKey, vmName))) {
                    hiddenClasses.addAll(keyCache.getClassesByKey(iKey));
                }
            }
        }
        return hiddenClasses;
    }

    /**
     * This method returns the list of BlackBerry specific VMs (JREs).
     *
     * @return bbVMlist List<IVMInstall>
     */
    public static List<IVMInstall> getInstalledBBVMs() {
        final IVMInstallType bbVMType = JavaRuntime.getVMInstallType(BlackBerryVMInstallType.VM_ID);
        if (bbVMType != null) {
            return Arrays.asList(bbVMType.getVMInstalls());
        }

        return new ArrayList<IVMInstall>();

    }

    /**
     * Gets all the installed VMs.
     *
     * @return the installed VMs
     */
    public static IVMInstall[] getInstalledVMs() {
        List<IVMInstall> vms = new ArrayList<IVMInstall>();
        for (IVMInstallType vmType : JavaRuntime.getVMInstallTypes()) {
            for (IVMInstall vm : vmType.getVMInstalls()) {
                vms.add(vm);
            }
        }
        return vms.toArray(new IVMInstall[vms.size()]);
    }

    /**
     * Gets the Installed BlackBerry specific VMs (JRE) with the matching ID.
     *
     * @param name
     *            the name
     *
     * @return the bBVM
     */
    public static IVMInstall getBBVM(String vmID) {
        final IVMInstallType bbVMType = JavaRuntime.getVMInstallType(BlackBerryVMInstallType.VM_ID);
        if (bbVMType != null) {
            return bbVMType.findVMInstall(vmID);
        }
        return null;
    }

    /**
     * This method returns the HashMap of BlackBerry specific VMs (JREs) Java doc locations with VMs names as a key.
     *
     * @return bbVMMap Map< String, String >
     */
    public static ArrayList<Map.Entry<String, String>> getJREDocsLocation() {
        Map<String, String> bbVMMap = new HashMap<String, String>();

        for (IVMInstall vm : VMUtils.getInstalledBBVMs()) {
            bbVMMap.put(vm.getName(), vm.getJavadocLocation().toString());
        }
        ArrayList<Map.Entry<String, String>> bbVMList = new ArrayList<Map.Entry<String, String>>(
                bbVMMap.entrySet());
        Collections.sort(bbVMList, new VMMapEntryComparator());
        return bbVMList;
    }

    /**
     * This method returns the default BlackBerry specific VM (JRE) based on following logic: When user already selected a
     * BlackBerry VM as a default installed VM then this method will return the default installed VM other wise it will iterate
     * through the BB specific VMs and pick the highest version as a default or return null when there is no BB specific VM is
     * available for iteration.
     *
     * @return defaultVM IVMInstall
     */
    public static IVMInstall getDefaultBBVM() {
        IVMInstall defaultVm = JavaRuntime.getDefaultVMInstall();

        if ((null == defaultVm) || !BlackBerryVMInstallType.VM_ID.equals(defaultVm.getVMInstallType().getId())) {
            defaultVm = null; // reset the default VM
            String vmId = null;
            // no default is found from workspace preferences and default
            // installed VM is either null or no BlackBerry type
            for (final IVMInstall vm : VMUtils.getInstalledBBVMs()) {
                if (BlackBerryVMInstallType.VM_ID.equals(vm.getVMInstallType().getId())) {
                    vmId = vm.getId();
                    if (defaultVm == null) {
                        defaultVm = vm;
                    } else {
                        if (defaultVm.getId().compareTo(vmId) < 0) {
                            defaultVm = vm;
                        }
                    }
                }
            }
        }

        return defaultVm; // when no bb vm exists returns null
    }

    /**
     * Creates a new VM based on the attributes specified in the given execution environment description file. The format of the
     * file is defined by <code>http://wiki.eclipse.org/Execution_Environment_Descriptions</code>.
     *
     * @param eeFile
     *            VM definition file
     * @param name
     *            name for the VM, or <code>null</code> if a default name should be assigned
     * @param id
     *            id to assign to the new VM
     *
     * @return VM standin
     *
     * @throws CoreException
     *             the core exception
     *
     * @exception CoreException
     *                if unable to create a VM from the given definition file
     */
    public static VMStandin createVMFromDefinitionFile(final File eeFile, String name, final String id)
            throws CoreException {
        if ((null == eeFile) || !eeFile.exists() || !eeFile.isFile()) {
            return null;
        }

        synchronized (eeFile) {
            final ExecutionEnvironmentDescription description = new ExecutionEnvironmentDescription(eeFile);
            final BlackBerryVMInstallType bbType = (BlackBerryVMInstallType) JavaRuntime
                    .getVMInstallType(BlackBerryVMInstallType.VM_ID);

            final IStatus defFileValidityStatus = BlackBerryVMInstallType.validateDefinitionFile(description);

            if (defFileValidityStatus.isOK()) {
                final VMStandin standin = new VMStandin(bbType, id);
                String vmName = name;
                if ((name == null) || (name.length() <= 0)) {
                    vmName = description.getProperty(ExecutionEnvironmentDescription.EE_NAME);
                    if (vmName == null) {
                        vmName = eeFile.getName();
                    }
                }
                standin.setName(vmName);

                final String home = description.getProperty(ExecutionEnvironmentDescription.JAVA_HOME);

                final File homeFile = new File(home);
                final IStatus installLocValidityStatus = bbType.validateInstallLocation(homeFile);
                if (!installLocValidityStatus.isOK()) {
                    throw new CoreException(installLocValidityStatus);
                }

                standin.setInstallLocation(new File(home));
                standin.setLibraryLocations(description.getLibraryLocations());
                standin.setVMArgs(description.getVMArguments());
                standin.setJavadocLocation(BlackBerryVMInstallType.getJavadocLocation(description.getProperties()));

                standin.setAttribute(BlackBerryVMInstallType.ATTR_EXECUTION_ENVIRONMENT_ID,
                        description.getProperty(ExecutionEnvironmentDescription.CLASS_LIB_LEVEL));

                File exe = description.getExecutable();

                if (exe == null) {
                    exe = description.getConsoleExecutable();
                }
                if (exe != null) {
                    try {
                        standin.setAttribute(BlackBerryVMInstallType.ATTR_JAVA_EXE, exe.getCanonicalPath());
                    } catch (final IOException e) {
                        throw new CoreException(new Status(IStatus.ERROR, ContextManager.PLUGIN_ID,
                                LaunchingMessages.JavaRuntime_24, e));
                    }
                }
                standin.setAttribute(BlackBerryVMInstallType.ATTR_JAVA_VERSION,
                        description.getProperty(ExecutionEnvironmentDescription.LANGUAGE_LEVEL));
                standin.setAttribute(BlackBerryVMInstallType.ATTR_DEFINITION_FILE, eeFile.getPath());
                standin.setAttribute(BlackBerryVMInstallType.ATTR_DEBUG_ARGS,
                        description.getProperty(ExecutionEnvironmentDescription.DEBUG_ARGS));
                standin.setAttribute(BlackBerryVMInstallType.ATTR_RAPC_OUTPUT_FOLDER,
                        description.getProperty(BlackBerryVMInstallType.EE_RAPC_OUTPUT_FOLDER));
                standin.setAttribute(BlackBerryVMInstallType.ATTR_CLASSPATH_PROVIDER,
                        RIMClasspathProvider.RIM_CLASSPATH_PROVIDER_ID);
                standin.setAttribute(BlackBerryVMInstallType.ATTR_DESCRIPTION,
                        description.getProperty(BlackBerryVMInstallType.EE_DESCRIPTION));
                standin.setAttribute(BlackBerryVMInstallType.ATTR_INTERNAL,
                        description.getProperty(BlackBerryVMInstallType.EE_INTERNAL));
                standin.setAttribute(BlackBerryVMInstallType.ATTR_DIRECTIVE,
                        description.getProperty(BlackBerryVMInstallType.EE_DIRECTIVE));
                standin.setAttribute(BlackBerryVMInstallType.ATTR_VERSION,
                        description.getProperty(BlackBerryVMInstallType.EE_VERSION));
                return standin;
            }
            _log.error("Failed createVMFromDefinitionFile: " + eeFile.getPath() + "| " + defFileValidityStatus);
            throw new CoreException(defFileValidityStatus);
        }
    }

    /**
     * Creates a new VM based on the attributes specified in the given execution environment description file. The format of the
     * file is defined by <code>http://wiki.eclipse.org/Execution_Environment_Descriptions</code>.
     *
     * @param eeFile
     *            VM definition file
     * @param force
     *            Boolean whether to force creation of VM depsite naming conflicts
     *
     * @return VM standin
     *
     * @throws CoreException
     *             the core exception
     *
     * @exception CoreException
     *                if unable to create a VM from the given definition file
     */
    public static VMStandin createVMFromDefinitionFile(final File eeFile, boolean force) throws CoreException {
        VMStandin vm = null;
        final BlackBerryVMInstallType blackBerryVMInstallType = (BlackBerryVMInstallType) JavaRuntime
                .getVMInstallType(BlackBerryVMInstallType.VM_ID);

        if (blackBerryVMInstallType == null) {
            throw new CoreException(new Status(IStatus.WARNING, ContextManager.PLUGIN_ID,
                    "Could not find instance of BlackBerry VM Install Type"));
        }

        final String vmName = VMUtils.getPropertyFromEEFile(eeFile, ExecutionEnvironmentDescription.EE_NAME);
        _log.trace("Attempting to create VM with name - " + vmName);

        if (force || (VMUtils.isVMNameValid(vmName) && (null == blackBerryVMInstallType.findVMInstall(vmName)))) {
            vm = VMUtils.createVMFromDefinitionFile(eeFile, vmName, vmName);
        } else {
            _log.trace("VM Creation skipped");
        }
        return vm;
    }

    /**
     * Checks if is vM name valid.
     *
     * @param newName
     *            the new name
     *
     * @return true, if is vM name valid
     */
    private static boolean isVMNameValid(final String newName) {
        if ((newName == null) || (newName.trim().length() == 0)) {
            return false;
        }

        if (VMUtils.isDuplicateName(newName)) {
            return false;
        }

        final IStatus s = ResourcesPlugin.getWorkspace().validateName(newName, IResource.FILE);
        if (!s.isOK()) {
            return false;
        }
        return true;

    }

    /**
     * Checks if is duplicate name.
     *
     * @param newName
     *            the new name
     *
     * @return true, if is duplicate name
     */
    private static boolean isDuplicateName(final String newName) {
        final IVMInstall[] vms = JavaRuntime.getVMInstallType(BlackBerryVMInstallType.VM_ID).getVMInstalls();
        for (final IVMInstall vm : vms) {
            if (newName.equals(vm.getName())) {
                return true;
            }
        }
        return false;
    }

    /**
     * Gets the string value of an EE property from a given EE file.
     *
     * @param eeFile
     *            the ee file
     * @param property
     *            the property
     *
     * @return the string value of the property
     */
    static public String getPropertyFromEEFile(final File eeFile, final String property) {
        if ((null != eeFile) && eeFile.exists() && eeFile.isFile()) {
            InputStream inputStream = null;
            Properties properties = null;
            WeakReference<Properties> propsStub = null;
            WeakReference<InputStream> streamStub = null;

            try {
                propsStub = new WeakReference<Properties>(new Properties());
                properties = propsStub.get();

                streamStub = new WeakReference<InputStream>(new FileInputStream(eeFile));
                inputStream = streamStub.get();

                properties.load(inputStream);

                final String id = properties.getProperty(property);

                return id;
            } catch (final FileNotFoundException e) {
                _log.error("", e); //$NON-NLS-1$
            } catch (final IOException e) {
                _log.error("", e); //$NON-NLS-1$
            } finally {
                if (null != properties) {
                    properties.clear();
                    if (propsStub != null) {
                        propsStub.clear();
                        propsStub = null;
                    }
                }
                if (null != inputStream) {
                    try {
                        inputStream.close();
                        if (streamStub != null) {
                            streamStub.clear();
                            streamStub = null;
                        }
                    } catch (final IOException e) {
                        _log.error("", e); //$NON-NLS-1$
                    }
                }
            }
        }

        return StringUtils.EMPTY;
    }

    /**
     * This method returns true when BlackBerry specific VM (JRE) is the default installed VM (JRE) in the workspace otherwise
     * false.
     *
     * @return boolean
     */
    public static boolean isBlackBerryRuntimeTheWorkspaceDefault() {
        final IVMInstall install = JavaRuntime.getDefaultVMInstall();

        if (null != install) {
            final IVMInstallType installType = install.getVMInstallType();

            if (BlackBerryVMInstallType.VM_ID.equals(installType.getId())) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks if the given <code>vm</code> is a BlackBerry vm.
     *
     * @param vm
     *            the vm
     *
     * @return true, if checks if is black berry vm
     */
    public static boolean isBlackBerryVM(IVMInstall vm) {
        final IVMInstallType installType = vm.getVMInstallType();

        if (BlackBerryVMInstallType.VM_ID.equalsIgnoreCase(installType.getId())) {
            return true;
        }
        return false;
    }

    /**
     * The Class VMComparator.
     */
    static class VMMapEntryComparator implements Comparator<Map.Entry<String, ?>> {

        /*
         * (non-Javadoc)
         *
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(final Map.Entry<String, ?> obj1, final Map.Entry<String, ?> obj2) {
            final String word1 = obj1.getKey();
            final String word2 = obj2.getKey();
            return word1.compareToIgnoreCase(word2);
        }
    }

    /**
     * The Class VMComparator.
     */
    static public class VMGeneralComparator implements Comparator<IVMInstall> {

        /*
         * (non-Javadoc)
         *
         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
         */
        public int compare(final IVMInstall obj1, final IVMInstall obj2) {
            final BlackBerrySDKInstall bbVM1 = (BlackBerrySDKInstall) obj1;
            final BlackBerrySDKInstall bbVM2 = (BlackBerrySDKInstall) obj2;
            final Version version1 = new Version(bbVM1.getVMVersion());
            final Version version2 = new Version(bbVM2.getVMVersion());
            return version1.compareTo(version2);
        }
    }

    /**
     * The class VMVersionComparator.
     *
     * @author bkurz
     *
     */
    public static class VMVersionComparator implements Comparator<String> {
        @Override
        public int compare(String o1, String o2) {
            String[] tokensFirstVersion = o1.split("[.]");
            String[] tokensSecondVersion = o2.split("[.]");

            for (int i = 0; i < tokensFirstVersion.length; i++) {
                if (Integer.valueOf(tokensFirstVersion[i]) < Integer.valueOf(tokensSecondVersion[i])) {
                    return -1;
                } else if (Integer.valueOf(tokensFirstVersion[i]) > Integer.valueOf(tokensSecondVersion[i])) {
                    return 1;
                }
            }
            return 0;
        }
    }

    /**
     * Find VM by the given name.
     *
     * @param vmName
     *            The VM name to be searched
     * @return The <code>IVMInstall</code> if found; or <code>null</code>
     */
    public static IVMInstall findVMByName(String vmName) {
        List<IVMInstall> vms = VMUtils.getInstalledBBVMs();
        for (IVMInstall vm : vms) {
            if (vm.getName().equals(vmName)) {
                return vm;
            }
        }
        return null;
    }

    /**
     * Find VM by the given id.
     *
     * @param vmId
     *            The VM id to be searched
     * @return The <code>IVMInstall</code> if found; or <code>null</code>
     */
    public static IVMInstall findVMById(String vmId) {
        List<IVMInstall> vms = VMUtils.getInstalledBBVMs();
        for (IVMInstall vm : vms) {
            if (vm.getId().equals(vmId)) {
                return vm;
            }
        }
        return null;
    }

    /**
     * Returns the version of the given VM. It looks from the last segment of "ee.description". If it is not a valid version
     * string (x.x.x.x), returns default version 0.0.0.0.
     *
     * @param vm
     *            The VM
     * @return The version of the VM.
     */
    public static String getVMVersion(IVMInstall vm) {
        BlackBerrySDKInstall bbVM = (BlackBerrySDKInstall) vm;

        String ver = bbVM.getAttribute(BlackBerryVMInstallType.ATTR_VERSION);
        // new VMs has version in ee.version property
        if (ver != null) {
            return ver;
        }

        String desc = bbVM.getAttribute(BlackBerryVMInstallType.ATTR_DESCRIPTION);
        // Handle old VMs that do not have the description attribute
        if (desc == null) {
            return IConstants.DEFAULT_VM_VERSION;
        }
        String[] tokens = desc.split(" ");
        String version = IConstants.DEFAULT_VM_VERSION;
        if (tokens.length > 0) {
            if (Pattern.matches("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+", tokens[tokens.length - 1])) {
                version = tokens[tokens.length - 1];
            } else {
                _log.error("Invalid VM version found on " + vm.getId());
            }
        }
        return version;
    }

    /**
     * Returns the SDK with the highest version number
     *
     * @return
     */
    public static IVMInstall getLatestSDK() {
        IVMInstall latestVMInstall = null;
        VMVersionComparator comparator = new VMVersionComparator();

        List<IVMInstall> installedSDK = VMUtils.getInstalledBBVMs();
        for (IVMInstall vmInstall : installedSDK) {
            if (latestVMInstall == null || comparator.compare(VMUtils.getVMVersion(latestVMInstall),
                    VMUtils.getVMVersion(vmInstall)) == -1) {
                latestVMInstall = vmInstall;
            }
        }
        return latestVMInstall;
    }

    /**
     * Returns if the given vm is an internal one (aka lynx)
     *
     * @param vm
     *            The given VM
     * @return <code>true</code> if yes; otherwise returns <code>false</code>
     */
    public static boolean isInternal(IVMInstall vm) {
        String isInternal = ((AbstractVMInstall) vm).getAttribute(BlackBerryVMInstallType.ATTR_INTERNAL);
        return isInternal != null && Integer.parseInt(isInternal) == 1;
    }

    /**
     * Gets the JRE level pre-defined preprocess directive for the given <code>bbVM</code>. If the .directive attribute is
     * specified in the .ee file (JAVA SDK after 12/17/09), will take precedence
     *
     * @param bbVM
     * @return
     */
    public static String getJREDirective(BlackBerrySDKInstall bbVM) {
        if (bbVM == null) {
            return IConstants.EMPTY_STRING;
        }
        String bbvmd = bbVM.getAttribute(BlackBerryVMInstallType.ATTR_DIRECTIVE);
        if (bbvmd == null || bbvmd.length() == 0) {
            bbvmd = ContextManager.getDefault().getPreferenceStore().getString(IConstants.JRE_DIRECTIVE_PREFIX_KEY)
                    + bbVM.getAttribute(BlackBerryVMInstallType.ATTR_RAPC_OUTPUT_FOLDER);
        }
        return bbvmd;
    }

    /**
     * Get the component pack level pre-defined preprocess directive for all installed BlackBerry JRE.
     *
     * @return
     */
    static public final List<String> getAllJREDirectives() {
        List<String> directives = new ArrayList<String>();
        List<IVMInstall> vmList = VMUtils.getInstalledBBVMs();
        Collections.sort(vmList, new VMUtils.VMGeneralComparator());
        BlackBerrySDKInstall bbVM;
        String JREDirective;
        for (int i = 0; i < vmList.size(); i++) {
            bbVM = (BlackBerrySDKInstall) vmList.get(i);
            JREDirective = VMUtils.getJREDirective(bbVM);
            if (!StringUtils.isBlank(JREDirective)) {
                directives.add(JREDirective);
            }
        }
        return directives;
    }

    /**
     * Get the component pack level pre-defined preprocess directive for the given <code>project</code>.
     *
     * @param project
     * @return
     */
    static public final String getJREDirective(IJavaProject project) {
        BlackBerrySDKInstall bbVM;
        try {
            IVMInstall vm = JavaRuntime.getVMInstall(project);
            if (!(vm instanceof BlackBerrySDKInstall)) {
                if (vm != null) {
                    _log.trace(vm.getName() + " is not a BlackBerry JRE");
                } else {
                    _log.trace(project.getProject().getName() + " does not have a valid BlackBerry JRE");
                }
                return IConstants.EMPTY_STRING;
            }
            bbVM = (BlackBerrySDKInstall) JavaRuntime.getVMInstall(project);
            return VMUtils.getJREDirective(bbVM);
        } catch (CoreException e) {
            _log.error(e.getMessage());
            return IConstants.EMPTY_STRING;
        }
    }
}