/******************************************************************************* * This file is protected by Copyright. * Please refer to the COPYRIGHT file distributed with this source distribution. * * This file is part of REDHAWK IDE. * * 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 *******************************************************************************/ package gov.redhawk.ide.debug.internal; import java.io.File; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import org.eclipse.core.externaltools.internal.IExternalToolConstants; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.emf.common.util.URI; import org.omg.CORBA.Any; import CF.DataType; import CF.ExecutableDevice; import gov.redhawk.ide.debug.LocalScaExecutableDevice; import gov.redhawk.ide.debug.LocalScaWaveform; import gov.redhawk.ide.debug.ScaDebugPlugin; import gov.redhawk.ide.debug.SpdLauncherUtil; import gov.redhawk.ide.debug.internal.variables.ExecParamResolver; import gov.redhawk.ide.debug.variables.LaunchVariables; import gov.redhawk.ide.sdr.util.AbstractEnvMap; import gov.redhawk.model.sca.ScaSimpleProperty; import mil.jpeojtrs.sca.spd.Code; import mil.jpeojtrs.sca.spd.Implementation; import mil.jpeojtrs.sca.spd.SoftPkg; import mil.jpeojtrs.sca.spd.SpdPackage; import mil.jpeojtrs.sca.util.AnyUtils; import mil.jpeojtrs.sca.util.CorbaUtils; import mil.jpeojtrs.sca.util.ScaEcoreUtils; /** * Utility class for configuring and using {@link ILaunch} and {@link ILaunchConfiguration} associated with launching * Redhawk components<br> * Includes a launch method for shared address space components intended to be the primary (and preferably only) * mechanism for launching * a shared address space component within a component host */ @SuppressWarnings("restriction") public class ComponentProgramLaunchUtils { private ComponentProgramLaunchUtils() { } /** * Retrieves the command-line arguments for the executable from the launch configuration and expands variable * references. This ensures variables related to running the SoftPkg (naming context, exec params, etc) are * expanded. * * @param spd The SoftPkg being executed * @param launch The launch that's about to occur * @param configuration A working copy of the launch's configuration * @throws CoreException */ public static void insertProgramArguments(final SoftPkg spd, final ILaunch launch, final ILaunchConfigurationWorkingCopy configuration) throws CoreException { final String args = configuration.getAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, ""); final String scaArgs = SpdLauncherUtil.insertProgramArguments(spd, args, launch, configuration); configuration.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, scaArgs); } /** * Launch a shared address space component, first either retrieving or launching a component host */ public static void launch(LocalScaWaveform waveform, ILaunchConfigurationWorkingCopy workingCopy, ComponentLaunch launch, SoftPkg spd, Implementation impl, String mode, IProgressMonitor monitor) throws OperationCanceledException, CoreException { final int WORK_CONTAINER_LAUNCH = 10, WORK_LAUNCH = 10, WORK_DEPS = 1, WORK_POST_LAUNCH = 100; SubMonitor subMonitor = SubMonitor.convert(monitor, WORK_CONTAINER_LAUNCH + WORK_LAUNCH + WORK_DEPS + WORK_POST_LAUNCH); // Grab an existing component host, or launch a new one LocalScaExecutableDevice componentHost = waveform.fetchComponentHost(mode, subMonitor.split(WORK_CONTAINER_LAUNCH)); final ExecutableDevice execDev = CF.ExecutableDeviceHelper.narrow(componentHost.getCorbaObj()); // Get path to the component's .so URI uri = spd.eResource().getURI(); String spdFileName = uri.lastSegment(); String resourcePath; if (uri.isPlatform()) { IPath absResourcePath = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true))).getRawLocation(); resourcePath = absResourcePath.toString().replace(spdFileName, impl.getCode().getEntryPoint()); } else { resourcePath = uri.toFileString().replace(spdFileName, impl.getCode().getEntryPoint()); } final String entryPoint = resourcePath; // Fetch implementation options/parameters/dependencies final DataType[] options = ComponentProgramLaunchUtils.getComponentOptions(spd, impl, launch); final DataType[] parameters = ComponentProgramLaunchUtils.getComponentParameters(spd, impl, launch); final String[] deps = ComponentProgramLaunchUtils.getComponentDependencies(impl, subMonitor.split(WORK_DEPS)); // Use ComponentHost to launch the component in a thread try { CorbaUtils.invoke(new Callable<Object>() { @Override public Object call() throws Exception { execDev.executeLinked(entryPoint, options, parameters, deps); return null; } }, subMonitor); subMonitor.worked(WORK_LAUNCH); } catch (InterruptedException e) { throw new OperationCanceledException(e.getMessage()); } SpdLauncherUtil.postLaunch(spd, workingCopy, mode, launch, subMonitor.split(WORK_POST_LAUNCH)); launch.setParent(componentHost.getLaunch()); } public static DataType[] getComponentOptions(SoftPkg spd, Implementation impl, ILaunch launch) { List<DataType> options = new ArrayList<DataType>(); Code code = impl.getCode(); if (code.getStackSize() != null) { Any stackSize = AnyUtils.toAny(code.getStackSize(), "ulong", false); options.add(new DataType(ExecutableDevice.STACK_SIZE_ID, stackSize)); } if (code.getPriority() != null) { Any priority = AnyUtils.toAny(code.getPriority(), "ulong", false); options.add(new DataType(ExecutableDevice.PRIORITY_ID, priority)); } // TODO: Handle affinity return options.toArray(new DataType[0]); } public static DataType[] getComponentParameters(SoftPkg spd, Implementation impl, ILaunch launch) throws CoreException { Any compId = AnyUtils.toAny(launch.getAttribute(LaunchVariables.COMPONENT_IDENTIFIER), "string", false); Any nameBinding = AnyUtils.toAny(launch.getAttribute(LaunchVariables.NAME_BINDING), "string", false); Any profileName = AnyUtils.toAny(launch.getAttribute(LaunchVariables.PROFILE_NAME), "string", false); Any namingContextIOR = AnyUtils.toAny(launch.getAttribute(LaunchVariables.NAMING_CONTEXT_IOR), "string", false); List<DataType> parameters = new ArrayList<DataType>(); parameters.add(new DataType(LaunchVariables.COMPONENT_IDENTIFIER, compId)); parameters.add(new DataType(LaunchVariables.NAME_BINDING, nameBinding)); parameters.add(new DataType(LaunchVariables.PROFILE_NAME, profileName)); parameters.add(new DataType(LaunchVariables.NAMING_CONTEXT_IOR, namingContextIOR)); List<ScaSimpleProperty> execParamList = ExecParamResolver.getExecParams(launch.getLaunchConfiguration(), spd, impl); for (ScaSimpleProperty simple : execParamList) { parameters.add(new DataType(simple.getId(), simple.toAny())); } return parameters.toArray(new DataType[0]); } public static String[] getComponentDependencies(Implementation impl, IProgressMonitor monitor) throws CoreException { List<String> deps = new ArrayList<String>(); List<Implementation> implList = AbstractEnvMap.getDependencyImplementations(impl); for (Implementation depImpl : implList) { String depLocalFile = ScaEcoreUtils.getFeature(depImpl, SpdPackage.Literals.IMPLEMENTATION__CODE, SpdPackage.Literals.CODE__LOCAL_FILE, SpdPackage.Literals.LOCAL_FILE__NAME); URI depSpdURI = depImpl.eResource().getURI(); IFileStore fileStore; try { fileStore = EFS.getStore(new java.net.URI(depSpdURI.toString())); } catch (URISyntaxException e) { throw new CoreException(new Status(Status.ERROR, ScaDebugPlugin.ID, e.getMessage(), e)); } File file = fileStore.toLocalFile(EFS.NONE, monitor); IPath depPath = new Path(file.getAbsolutePath()).removeLastSegments(1).append(depLocalFile); deps.add(depPath.toString()); } return deps.toArray(new String[0]); } }