/* * 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.ui.launchers; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import net.rim.ejde.internal.core.IConstants; import net.rim.ejde.internal.launching.DeviceInfo; import net.rim.ejde.internal.launching.DeviceProfileManager; import net.rim.ejde.internal.launching.IDeviceLaunchConstants; import net.rim.ejde.internal.launching.IFledgeLaunchConstants; import net.rim.ejde.internal.launching.IRunningFledgeLaunchConstants; import net.rim.ejde.internal.model.BlackBerryVMInstallType; import net.rim.ejde.internal.util.Messages; import net.rim.ejde.internal.util.NatureUtils; import net.rim.ejde.internal.util.ProjectUtils; import net.rim.ejde.internal.util.StatusFactory; import net.rim.ejde.internal.util.VMUtils; import net.rim.ide.SettableProperty; import net.rim.ide.SettablePropertyGroup; import net.rim.ide.SimulatorProfiles; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.launching.AbstractVMInstall; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.osgi.util.NLS; /** * Utility class used by launch configuration. * * @author dmeng * */ public class LaunchUtils { private static Logger _logger = Logger.getLogger( LaunchUtils.class ); /** * Returns device info for the given VM. * * @param vm * The BlackBerry VM * @return List of <code>DeviceInfo</code> */ public static List< DeviceInfo > getDevicesInfo( IVMInstall vm ) { List< DeviceInfo > deviceList = DeviceProfileManager.getInstance().getDeviceProfiles( vm ); return deviceList; } /** * Returns the default device info in the given VM. * * @param vm * The VM * @return The default device info */ public static DeviceInfo getDefaultDeviceInfo( IVMInstall vm ) { DeviceInfo defaultDevice = DeviceProfileManager.getInstance().getDefaultDevice( vm ); return defaultDevice; } /** * Returns the device info for the given simulator profile. * * @param profiles * The <code>SimulatorProfiles</code> * @param profileName * The profile name * @return The device info in the given profile */ public static List< DeviceInfo > getDevicesInfo( SimulatorProfiles profiles, String profileName ) { List< DeviceInfo > deviceNames = new ArrayList< DeviceInfo >(); SettablePropertyGroup[] propGroups = profiles.getSettableProperties( profileName ); for( int groupIndex = 0; groupIndex < propGroups.length; groupIndex++ ) { SettableProperty[] properties = propGroups[ groupIndex ].getProperties(); for( int propIndex = 0; propIndex < properties.length; propIndex++ ) { if( properties[ propIndex ].getLabel().equals( IFledgeLaunchConstants.SETTABLE_PROPERTY_DEVICE ) ) { String[] choices = properties[ propIndex ].getChoices(); // filter out Default and blank for( int k = 0; k < choices.length; k++ ) { if( !choices[ k ].equals( IConstants.EMPTY_STRING ) && !choices[ k ].equals( IFledgeLaunchConstants.SETTABLE_PROPERTY_DEVICE_DEFAULT ) ) { // for default simulators, don't need set directory and config file name deviceNames.add( new DeviceInfo( IFledgeLaunchConstants.DEFAULT_SIMULATOR_BUNDLE_NAME, choices[ k ], "", choices[ k ] ) ); } } return deviceNames; } } } return Collections.emptyList(); } /** * Returns BlackBerry VM used to launch the given projects. * * @param projects * The list of <code>IProject</code> * @return The <code>IVMInstall</code> or <code>null</code> if not found. */ public static IVMInstall getDefaultLaunchVM( Collection< IProject > projects ) { IVMInstall targetVM = null; for( IProject project : projects ) { IVMInstall vm = ProjectUtils.getVMForProject( JavaCore.create( project ) ); if( vm != null ) { if( targetVM != null ) { // use the highest version of VM if( vm.getId().compareTo( targetVM.getId() ) > 0 ) { targetVM = vm; } } else { targetVM = vm; } } } return targetVM; } /** * Get the projects defined in the given launch configuration. * * @param configuration * The launch configuration * @return The collection of projects */ @SuppressWarnings("unchecked") public static Set< IProject > getProjectsFromConfiguration( ILaunchConfiguration configuration ) { List< String > checkedProjectNames; try { checkedProjectNames = configuration.getAttribute( IFledgeLaunchConstants.ATTR_DEPLOYED_PROJECTS, Collections.EMPTY_LIST ); } catch( CoreException e ) { _logger.error( e ); return Collections.emptySet(); } Set< IProject > checkedProjects = new HashSet< IProject >(); for( String name : checkedProjectNames ) { IResource ires = ResourcesPlugin.getWorkspace().getRoot().findMember( name ); if( ires != null && ires instanceof IProject ) { IProject project = (IProject) ires; // this also filters out closed projects if( project.isOpen() ) { checkedProjects.add( project ); } } } return checkedProjects; } /** * Get the highest VM in the given projects. * * @param projects * The projects * @return The highest version of VM or <code>null</code> if all VMs are uninstalled */ public static IVMInstall getHighestVMInProjects( Collection< IProject > projects ) { IVMInstall targetVM = null; for( IProject project : projects ) { IVMInstall vm = ProjectUtils.getVMForProject( JavaCore.create( project ) ); // The VM must be available if( vm != null ) { if( targetVM != null ) { if( vm.getId().compareTo( targetVM.getId() ) > 0 ) { targetVM = vm; } } else { targetVM = vm; } } } return targetVM; } /** * Returns current running BlackBerry launch, could be Simulator, Device or Running Simulator launch. * * @return The BlackBerry launch or <code>null</code> if running BB launch does not exist. */ public static ILaunch getRunningBBLaunch() { ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches(); for( int i = 0; i < launches.length; i++ ) { if( !launches[ i ].isTerminated() ) { try { ILaunchConfiguration configuration = launches[ i ].getLaunchConfiguration(); if( configuration != null ) { ILaunchConfigurationType launchType = configuration.getType(); if( launchType.getIdentifier().equals( IFledgeLaunchConstants.LAUNCH_CONFIG_ID ) || launchType.getIdentifier().equals( IRunningFledgeLaunchConstants.LAUNCH_CONFIG_ID ) || launchType.getIdentifier().equals( IDeviceLaunchConstants.LAUNCH_CONFIG_ID ) ) { return launches[ i ]; } } } catch( CoreException e ) { _logger.error( e ); } } } return null; } /** * Get list of <code>IProject</code> from the selection. * * @param selection * @return The list of <code>IProject</code> */ public static List< IProject > getSelectedProjects( StructuredSelection selection ) { Object[] items = selection.toArray(); List< IProject > projects = new ArrayList< IProject >(); IProject iproject; for( int i = 0; i < items.length; i++ ) { iproject = null; if( items[ i ] instanceof IAdaptable ) { Object ires = ( (IAdaptable) items[ i ] ).getAdapter( IResource.class ); if( ires != null ) { iproject = ( (IResource) ires ).getProject(); } } if( iproject != null ) { if( NatureUtils.hasBBNature( iproject ) && !projects.contains( iproject ) ) { projects.add( iproject ); } } } return projects; } /** * Returns the VM in the given launch configuration. * * @param configuration * The <code>ILaunchConfiguration</code> * @return The <code>IVMInstall</code> or <code>null</code> if BB-VM is not found. */ public static IVMInstall getVMFromConfiguration( ILaunchConfiguration configuration ) { IVMInstall vm = null; try { int vmType = configuration.getAttribute( IFledgeLaunchConstants.ATTR_JRE_TYPE, IFledgeLaunchConstants.DEFAULT_JRE_TYPE ); if( vmType == IFledgeLaunchConstants.JRE_TYPE_PROJECT ) { Set< IProject > projects = getProjectsFromConfiguration( configuration ); vm = getDefaultLaunchVM( projects ); } else if( vmType == IFledgeLaunchConstants.JRE_TYPE_ALTERNATE ) { String vmId = configuration.getAttribute( IFledgeLaunchConstants.ATTR_JRE_ID, StringUtils.EMPTY ); if( !vmId.equals( StringUtils.EMPTY ) ) { vm = VMUtils.findVMById( vmId ); } } } catch( CoreException e ) { _logger.error( e ); } return vm; } /** * Returns the device name associated with the given launch configuration. * * @param configuration * The launch configuration * @return The device name or empty string if any error occurs */ public static DeviceInfo getDeviceInfo( ILaunchConfiguration configuration ) { try { String simDir = configuration.getAttribute( IFledgeLaunchConstants.ATTR_GENERAL_SIM_DIR, StringUtils.EMPTY ); String bundleName = configuration.getAttribute( IFledgeLaunchConstants.ATTR_GENERAL_BUNDLE, StringUtils.EMPTY ); String deviceName = configuration.getAttribute( IFledgeLaunchConstants.ATTR_GENERAL_DEVICE, StringUtils.EMPTY ); String configFile = configuration.getAttribute( IFledgeLaunchConstants.ATTR_GENERAL_CONFIG_FILE, StringUtils.EMPTY ); IVMInstall vm = LaunchUtils.getVMFromConfiguration( configuration ); List< DeviceInfo > devices = LaunchUtils.getDevicesInfo( vm ); DeviceInfo di = new DeviceInfo( bundleName, deviceName, simDir, configFile ); if( !devices.contains( di ) ) { return LaunchUtils.getDefaultDeviceInfo( vm ); } return di; } catch( CoreException e ) { _logger.error( e ); } return null; } /** * Returns the String attribute value stored in the launch configuration. * * @param configuration * The launch configuration * @param attribute * The attribute * @return The attribute value */ public static String getStringAttribute( ILaunchConfiguration configuration, String attribute, String defaultValue ) { String ret = defaultValue; try { ret = configuration.getAttribute( attribute, defaultValue ); } catch( CoreException e ) { _logger.error( e.getMessage() ); } return ret; } /** * Returns the boolean attribute value stored in the launch configuration. * * @param configuration * The launch configuration * @param attribute * The attribute * @return The attribute value */ public static boolean getBooleanAttribute( ILaunchConfiguration configuration, String attribute, boolean defaultValue ) { boolean ret = defaultValue; try { ret = configuration.getAttribute( attribute, defaultValue ); } catch( CoreException e ) { _logger.error( e.getMessage() ); } return ret; } /** * Returns the simulator path for the given VM. * * @param vm * The VM * @return The simulator path */ public static String getSimualtorPath( IVMInstall vm ) { String simulatorPath; String isInternal = ( (AbstractVMInstall) vm ).getAttribute( BlackBerryVMInstallType.ATTR_INTERNAL ); if( isInternal != null && Integer.parseInt( isInternal ) == 1 ) { simulatorPath = vm.getInstallLocation().getPath() + File.separator + "debug"; } else { simulatorPath = vm.getInstallLocation().getPath() + File.separator + "simulator"; } return simulatorPath; } /** * Returns the fledge.exe path for the given VM. * * @param vm * The VM * @return The fledge.exe path */ public static String getFledgeExePath( IVMInstall vm ) { String fledgePath; String isInternal = ( (AbstractVMInstall) vm ).getAttribute( BlackBerryVMInstallType.ATTR_INTERNAL ); if( isInternal != null && Integer.parseInt( isInternal ) == 1 ) { fledgePath = vm.getInstallLocation().getPath() + File.separator + "fledge" + File.separator + "bin"; } else { fledgePath = vm.getInstallLocation().getPath() + File.separator + "simulator"; } return fledgePath; } public static DeviceInfo getDeviceToLaunch( ILaunchConfiguration configuration ) throws CoreException { String bundleName = configuration.getAttribute( IFledgeLaunchConstants.ATTR_GENERAL_BUNDLE, StringUtils.EMPTY ); String simDir = configuration.getAttribute( IFledgeLaunchConstants.ATTR_GENERAL_SIM_DIR, StringUtils.EMPTY ); String deviceName = configuration.getAttribute( IFledgeLaunchConstants.ATTR_GENERAL_DEVICE, StringUtils.EMPTY ); String configFileName = configuration.getAttribute( IFledgeLaunchConstants.ATTR_GENERAL_CONFIG_FILE, StringUtils.EMPTY ); IVMInstall vm = LaunchUtils.getVMFromConfiguration( configuration ); List< DeviceInfo > devices = LaunchUtils.getDevicesInfo( vm ); if( devices.isEmpty() ) { throw new CoreException( StatusFactory.createErrorStatus( NLS.bind( Messages.Launch_Error_DeviceNotFound, vm.getId() ) ) ); } if( !devices.contains( new DeviceInfo( bundleName, deviceName, simDir, configFileName ) ) ) { // JRE is changed, choose the default device instead DeviceInfo di = LaunchUtils.getDefaultDeviceInfo( vm ); if( di != null ) { bundleName = di.getBundleName(); simDir = di.getDirectory(); deviceName = di.getDeviceName(); configFileName = di.getConfigName(); // save the changes ILaunchConfigurationWorkingCopy workingCopy = configuration.getWorkingCopy(); workingCopy.setAttribute( IFledgeLaunchConstants.ATTR_GENERAL_BUNDLE, bundleName ); workingCopy.setAttribute( IFledgeLaunchConstants.ATTR_GENERAL_SIM_DIR, simDir ); workingCopy.setAttribute( IFledgeLaunchConstants.ATTR_GENERAL_DEVICE, deviceName ); workingCopy.setAttribute( IFledgeLaunchConstants.ATTR_GENERAL_CONFIG_FILE, configFileName ); workingCopy.doSave(); } else { throw new CoreException( StatusFactory.createErrorStatus( NLS.bind( Messages.Launch_Error_DefaultDeviceNotFound, vm.getId() ) ) ); } } return new DeviceInfo( bundleName, deviceName, simDir, configFileName ); } /** * Close the given launch, it terminates the launch first (if supported) and remove it from launch manager. * * @param launch * The launch to be closed * @throws DebugException */ public static void closeLaunch( ILaunch launch ) throws DebugException { if( launch != null ) { if( launch.canTerminate() ) { launch.terminate(); } DebugPlugin.getDefault().getLaunchManager().removeLaunch( launch ); } } /** * Returns the VM name used in the given launch configuration. * * @param configuration * The launch configuration * @return The VM name or "undefined" if the vm has been removed */ public static String getVMNameFromConfiguration( ILaunchConfiguration configuration ) { String vmName = "undefined"; try { int vmType = configuration.getAttribute( IFledgeLaunchConstants.ATTR_JRE_TYPE, IFledgeLaunchConstants.DEFAULT_JRE_TYPE ); if( vmType == IFledgeLaunchConstants.JRE_TYPE_PROJECT ) { Set< IProject > projects = getProjectsFromConfiguration( configuration ); IVMInstall vm = getDefaultLaunchVM( projects ); if( vm != null ) { vmName = vm.getName(); } } else if( vmType == IFledgeLaunchConstants.JRE_TYPE_ALTERNATE ) { vmName = configuration.getAttribute( IFledgeLaunchConstants.ATTR_JRE_ID, StringUtils.EMPTY ); } } catch( CoreException e ) { _logger.error( e ); } return vmName; } }