Java tutorial
/******************************************************************************* * 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 gov.redhawk.ide.debug.LocalSca; import gov.redhawk.ide.debug.LocalScaWaveform; import gov.redhawk.ide.debug.NotifyingNamingContext; import gov.redhawk.ide.debug.ScaDebugFactory; import gov.redhawk.ide.debug.ScaDebugPlugin; import gov.redhawk.ide.debug.internal.cf.extended.impl.ApplicationImpl; import gov.redhawk.model.sca.RefreshDepth; import gov.redhawk.model.sca.ScaAbstractProperty; import gov.redhawk.model.sca.ScaComponent; import gov.redhawk.model.sca.ScaPort; import gov.redhawk.model.sca.ScaUsesPort; import gov.redhawk.model.sca.ScaWaveform; import gov.redhawk.model.sca.commands.ScaModelCommand; import gov.redhawk.sca.util.SubMonitor; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import mil.jpeojtrs.sca.partitioning.ComponentProperties; import mil.jpeojtrs.sca.partitioning.PartitioningPackage; import mil.jpeojtrs.sca.prf.AbstractPropertyRef; import mil.jpeojtrs.sca.prf.PropertyConfigurationType; import mil.jpeojtrs.sca.prf.SimpleRef; import mil.jpeojtrs.sca.prf.util.PropertiesUtil; import mil.jpeojtrs.sca.sad.HostCollocation; import mil.jpeojtrs.sca.sad.SadComponentInstantiation; import mil.jpeojtrs.sca.sad.SadComponentPlacement; import mil.jpeojtrs.sca.sad.SadConnectInterface; import mil.jpeojtrs.sca.sad.SoftwareAssembly; import mil.jpeojtrs.sca.spd.SoftPkg; import mil.jpeojtrs.sca.util.AnyUtils; import mil.jpeojtrs.sca.util.DceUuidUtil; import mil.jpeojtrs.sca.util.QueryParser; import mil.jpeojtrs.sca.util.ScaEcoreUtils; import mil.jpeojtrs.sca.util.ScaFileSystemConstants; import org.apache.commons.lang.ArrayUtils; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.util.FeatureMap.Entry; import org.eclipse.jdt.annotation.Nullable; import org.jacorb.naming.Name; import org.omg.CORBA.Any; import org.omg.CORBA.SystemException; import org.omg.CosNaming.NameComponent; import org.omg.CosNaming.NamingContextExt; import org.omg.CosNaming.NamingContextExtHelper; import org.omg.CosNaming.NamingContextPackage.AlreadyBound; import org.omg.CosNaming.NamingContextPackage.CannotProceed; import org.omg.CosNaming.NamingContextPackage.InvalidName; import org.omg.CosNaming.NamingContextPackage.NotFound; import CF.DataType; import CF.PortPackage.InvalidPort; import CF.PortPackage.OccupiedPort; import CF.PropertySetPackage.InvalidConfiguration; import CF.PropertySetPackage.PartialConfiguration; /** * */ public class LocalApplicationFactory { private final Map<String, String> implMap; private final LocalSca localSca; private final String mode; private final ILaunch launch; private final DataType[] assemblyConfig; private final DataType[] assemblyExec; private final NotifyingNamingContext namingContext; public LocalApplicationFactory(final LocalSca localSca) { this.implMap = null; this.localSca = localSca; this.mode = ILaunchManager.RUN_MODE; this.launch = null; this.assemblyExec = null; this.assemblyConfig = null; this.namingContext = this.localSca.getRootContext(); } public LocalApplicationFactory(final Map<String, String> implMap, final LocalSca localSca, final String mode, final ILaunch launch, final DataType[] assemblyExec, final DataType[] assemblyConfig) { this.implMap = implMap; this.localSca = localSca; this.mode = mode; this.launch = launch; this.assemblyExec = assemblyExec; this.assemblyConfig = assemblyConfig; this.namingContext = this.localSca.getRootContext(); } public static NotifyingNamingContext createWaveformContext(NotifyingNamingContext parent, String name) throws CoreException { NamingContextExt retVal = null; String adjustedName = name; for (int i = 2; retVal == null; i++) { try { retVal = NamingContextExtHelper.narrow(parent.bind_new_context(Name.toName(adjustedName))); } catch (AlreadyBound e) { adjustedName = name + "_" + i; } catch (NotFound e) { throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, "Failed to create application: " + adjustedName + " " + e.getMessage(), e)); } catch (CannotProceed e) { throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, "Failed to create application: " + adjustedName + " " + e.getMessage(), e)); } catch (InvalidName e) { throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, "Failed to create application: " + adjustedName + " " + e.getMessage(), e)); } } return parent.findContext(retVal); } /** * Carries out all the steps necessary to launch a waveform in the sandbox, including: * <ul> * <li>Launching components</li> * <li>Configuring components</li> * <li>Making waveform connections</li> * </ul> * @param sad * @param name * @param monitor * @return * @throws CoreException */ public LocalScaWaveform create(final SoftwareAssembly sad, String name, final IProgressMonitor monitor) throws CoreException { final SubMonitor progress = SubMonitor.convert(monitor, 100); String adjustedName = name; // Try and narrow to the given name. If an already bound exception occurs, append _ + i to the end and try again // until // we've found a good name. ApplicationImpl app = null; LocalScaWaveform waveform = null; try { progress.subTask("Create application"); final String appId = DceUuidUtil.createDceUUID(); final String profile = sad.eResource().getURI().path(); waveform = ScaDebugFactory.eINSTANCE.createLocalScaWaveform(); waveform.setProfile(profile); waveform.setLaunch(this.launch); waveform.setMode(this.launch.getLaunchMode()); waveform.setNamingContext(LocalApplicationFactory.createWaveformContext(namingContext, adjustedName)); app = new ApplicationImpl(waveform, appId, adjustedName); app.setLaunching(true); this.launch.addProcess(app); waveform.setLocalApp(app); progress.subTask("Bind application"); LocalApplicationFactory.bindApp(app); progress.worked(1); URI uri = sad.eResource().getURI(); Map<String, String> query = new HashMap<String, String>(QueryParser.parseQuery(uri.query())); query.put(ScaFileSystemConstants.QUERY_PARAM_WF, waveform.getIor()); String queryStr = QueryParser.createQuery(query); URI sadUri = URI.createHierarchicalURI(uri.scheme(), uri.authority(), uri.device(), uri.segments(), queryStr, uri.fragment()); waveform.setProfileURI(sadUri); waveform.fetchProfileObject(null); final ScaWaveform tmpWaveform = waveform; ScaModelCommand.execute(this.localSca, new ScaModelCommand() { @Override public void execute() { LocalApplicationFactory.this.localSca.getWaveforms().add(tmpWaveform); } }); progress.worked(1); progress.subTask("Launch components"); launchComponents(progress.newChild(90), app, sad); progress.subTask("Configure components"); configureComponents(app, sad, this.assemblyConfig); progress.worked(4); progress.subTask("Create connections"); createConnections(app, sad); progress.worked(3); } catch (final SystemException e) { throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, "Failed to create application: " + adjustedName + " " + e.getMessage(), e)); } finally { if (app != null) { app.setLaunching(false); } } if (app != null && waveform != null) { progress.subTask("Refresh"); SubMonitor subTask = progress.newChild(1); try { waveform.refresh(subTask, RefreshDepth.FULL); } catch (InterruptedException e) { // PASS } app.getStreams().getOutStream().println("Done"); } progress.done(); return waveform; } private String getImplId(final SadComponentInstantiation comp) { String retVal = null; if (this.implMap != null) { retVal = this.implMap.get(comp.getId()); } if (retVal == null) { retVal = comp.getPlacement().getComponentFileRef().getFile().getSoftPkg().getImplementation().get(0) .getId(); } return retVal; } /** * Performs the initial configure call on each component in the waveform * * @param app * @param sad * @param assemblyConfig * @throws CoreException */ protected void configureComponents(final ApplicationImpl app, final SoftwareAssembly sad, final DataType[] assemblyConfig) { app.getStreams().getOutStream().println("Configuring Components..."); for (final ScaComponent comp : app.getLocalWaveform().getComponents()) { try { app.getStreams().getOutStream().println("Configuring component: " + comp.getName()); configureComponent(app, comp); app.getStreams().getOutStream().println(""); } catch (final InvalidConfiguration e) { app.logException( "WARNING: Error while configuring component: " + comp.getName() + " InvalidConfiguration ", e); } catch (final PartialConfiguration e) { app.logException( "WARNING: Error while configuring component: " + comp.getName() + " PartialConfiguration ", e); } } } /** * Launches each component of the waveform * * @param monitor * @param app * @param sad * @param config * @throws CoreException */ protected void launchComponents(IProgressMonitor monitor, final ApplicationImpl app, final SoftwareAssembly sad) throws CoreException { final List<SadComponentInstantiation> instantiations = getComponentInstantiations(sad); final SubMonitor progress = SubMonitor.convert(monitor, instantiations.size()); app.getStreams().getOutStream().println("Launching components..."); for (final SadComponentInstantiation comp : instantiations) { progress.subTask(String.format("Launch component instance '%s'", comp.getUsageName())); URI spdUri = getSpdURI(comp); if (spdUri == null) { String errorMsg = String.format("Failed to find SPD for component: %s", comp.getUsageName()); throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, errorMsg)); } else { app.launch(comp.getUsageName(), createExecParam(comp), spdUri, getImplId(comp), this.mode); } app.getStreams().getOutStream().println("\n"); progress.worked(1); } } public static void bindApp(final ApplicationImpl app) throws CoreException { app.getStreams().getOutStream().println("Binding application..."); try { NamingContextExt context = app.getWaveformContext(); NameComponent[] name = Name.toName(app.name()); org.omg.CORBA.Object obj = app.getLocalWaveform().getCorbaObj(); context.bind(name, obj); app.getStreams().getOutStream().println("Done Binding application."); } catch (final NotFound e) { throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, "Failed to bind application to context " + e.getMessage(), e)); } catch (final CannotProceed e) { throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, "Failed to bind application to context " + e.getMessage(), e)); } catch (final InvalidName e) { throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, "Failed to bind application to context " + e.getMessage(), e)); } catch (final AlreadyBound e) { throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, "Failed to bind application to context " + e.getMessage(), e)); } catch (final SystemException e) { throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, "Failed to bind application to context " + e.getMessage(), e)); } } private void createConnections(final ApplicationImpl app, final SoftwareAssembly sad) throws CoreException { if (sad.getConnections() != null) { app.getStreams().getOutStream().println("Making connections..."); for (final SadConnectInterface connection : sad.getConnections().getConnectInterface()) { app.getStreams().getOutStream().println("Creating connection " + connection.getId()); org.omg.CORBA.Object target = null; if (connection.getProvidesPort() != null) { final String providesId = connection.getProvidesPort().getProvidesIdentifier(); if (connection.getProvidesPort().getComponentInstantiationRef() != null) { final String componentRefId = connection.getProvidesPort().getComponentInstantiationRef() .getRefid(); final ScaComponent componentForPort = app.getLocalWaveform() .getScaComponent(componentRefId); if (componentForPort == null) { String errorMsg = String.format( "Couldn't find component instance '%s' to make waveform connection '%s'", componentRefId, connection.getId()); throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, errorMsg)); } target = componentForPort.getScaPort(providesId).getCorbaObj(); } } else if (connection.getComponentSupportedInterface() != null) { final String componentRefId = connection.getComponentSupportedInterface() .getComponentInstantiationRef().getRefid(); final ScaComponent component = app.getLocalWaveform().getScaComponent(componentRefId); if (component == null) { String errorMsg = String.format( "Couldn't find component instance '%s' to make waveform connection '%s'", componentRefId, connection.getId()); throw new CoreException(new Status(IStatus.ERROR, ScaDebugPlugin.ID, errorMsg)); } target = component.getCorbaObj(); } else { app.getStreams().getErrStream() .println("Unsupported target connection type for connection: " + connection.getId()); } if (target != null) { final String usesID = connection.getUsesPort().getUsesIndentifier(); if (connection.getUsesPort().getComponentInstantiationRef() == null) { app.getStreams().getErrStream() .println("Failed to create connection " + connection.getId()); continue; } final ScaComponent component = app.getLocalWaveform() .getScaComponent(connection.getUsesPort().getComponentInstantiationRef().getRefid()); final ScaPort<?, ?> port = component.getScaPort(usesID); if (port instanceof ScaUsesPort) { final ScaUsesPort usesPort = (ScaUsesPort) port; try { usesPort.connectPort(target, connection.getId()); } catch (final InvalidPort e) { app.getStreams().getErrStream() .println("Failed to create connection " + connection.getId()); } catch (final OccupiedPort e) { app.getStreams().getErrStream() .println("Failed to create connection " + connection.getId()); } } } } app.getStreams().getOutStream().println("Done making connections"); } } private void configureComponent(ApplicationImpl app, final ScaComponent comp) throws InvalidConfiguration, PartialConfiguration { DataType[] configuration = getConfiguration(comp); if (configuration == null || configuration.length == 0) { app.getStreams().getOutStream().println("\tNo configuration."); return; } if (this.assemblyConfig != null && isAssemblyController(comp.getComponentInstantiation())) { configuration = this.assemblyConfig; } for (DataType t : configuration) { app.getStreams().getOutStream().println(LocalApplicationFactory.toString(t)); } comp.configure(configuration); comp.fetchProperties(null); } public static String toString(DataType t) { Object value = AnyUtils.convertAny(t.value); if (value instanceof DataType[]) { StringBuilder builder = new StringBuilder(); builder.append("\t" + t.id + " = {"); for (DataType child : (DataType[]) value) { builder.append("\n\t\t" + LocalApplicationFactory.toString(child)); } builder.append("\n\t}"); return builder.toString(); } else if (value instanceof DataType) { return "\t" + t.id + " = {" + LocalApplicationFactory.toString((DataType) value) + "}"; } else if (value instanceof Any[]) { StringBuilder builder = new StringBuilder(); builder.append("\t" + t.id + " = [] {"); int i = 0; for (Any child : (Any[]) value) { builder.append("\n\t\t[" + i++ + "] = "); Object childValue = AnyUtils.convertAny(child); String valueStr; if (childValue instanceof DataType) { valueStr = LocalApplicationFactory.toString((DataType) childValue); } else if (childValue instanceof DataType[]) { StringBuilder valueStrBuilder = new StringBuilder(); valueStrBuilder.append("{"); for (DataType childType : (DataType[]) childValue) { valueStrBuilder.append("\n\t\t" + LocalApplicationFactory.toString(childType)); } valueStrBuilder.append("\n\t\t}"); valueStr = valueStrBuilder.toString(); } else { valueStr = String.valueOf(childValue); } builder.append(valueStr); } builder.append("\n\t}"); return builder.toString(); } else if (value != null && value.getClass().isArray()) { return "\t" + t.id + " = " + ArrayUtils.toString(value); } else { return "\t" + t.id + " = " + value; } } private DataType[] getConfiguration(final ScaComponent comp) { final Map<String, DataType> retVal = new HashMap<String, DataType>(); comp.fetchProperties(null); for (final ScaAbstractProperty<?> prop : comp.getProperties()) { if (PropertiesUtil.canConfigure(prop.getDefinition())) { retVal.put(prop.getId(), new DataType(prop.getId(), prop.toAny())); } } final ScaWaveform waveform = comp.getWaveform(); final SoftwareAssembly sad = waveform.getProfileObj(); SadComponentInstantiation compInst = null; for (final SadComponentInstantiation ci : getComponentInstantiations(sad)) { if (ci.getId().equals(comp.getInstantiationIdentifier())) { compInst = ci; break; } } if (compInst == null) { throw new IllegalStateException("Unable to find component instantiation"); } final ComponentProperties props = compInst.getComponentProperties(); if (props != null) { // Override default values for (final Entry entry : props.getProperties()) { if (entry.getValue() instanceof AbstractPropertyRef<?>) { final AbstractPropertyRef<?> ref = (AbstractPropertyRef<?>) entry.getValue(); if (retVal.containsKey(ref.getRefID())) { retVal.put(ref.getRefID(), new DataType(ref.getRefID(), ref.toAny())); } } } } return retVal.values().toArray(new DataType[retVal.size()]); } private List<SadComponentInstantiation> getComponentInstantiations(final SoftwareAssembly sad) { final List<SadComponentInstantiation> retVal = new ArrayList<SadComponentInstantiation>(); if (sad.getPartitioning() != null) { for (final SadComponentPlacement cp : sad.getPartitioning().getComponentPlacement()) { retVal.addAll(cp.getComponentInstantiation()); } for (final HostCollocation hc : sad.getPartitioning().getHostCollocation()) { for (final SadComponentPlacement cp : hc.getComponentPlacement()) { retVal.addAll(cp.getComponentInstantiation()); } } } return retVal; } private static final EStructuralFeature[] PATH = new EStructuralFeature[] { PartitioningPackage.Literals.COMPONENT_INSTANTIATION__PLACEMENT, PartitioningPackage.Literals.COMPONENT_PLACEMENT__COMPONENT_FILE_REF, PartitioningPackage.Literals.COMPONENT_FILE_REF__FILE, PartitioningPackage.Literals.COMPONENT_FILE__SOFT_PKG }; @Nullable private URI getSpdURI(@Nullable final SadComponentInstantiation comp) { final SoftPkg spd = ScaEcoreUtils.getFeature(comp, LocalApplicationFactory.PATH); if (spd != null && spd.eResource() != null) { return spd.eResource().getURI(); } else { return null; } } private DataType[] createExecParam(final SadComponentInstantiation comp) { if (this.assemblyExec != null && isAssemblyController(comp)) { return this.assemblyExec; } final ComponentProperties props = comp.getComponentProperties(); final List<DataType> retVal = new ArrayList<DataType>(); if (props != null) { for (final Entry entry : props.getProperties()) { if (entry.getValue() instanceof SimpleRef) { final SimpleRef ref = (SimpleRef) entry.getValue(); if (ref.getProperty().isKind(PropertyConfigurationType.EXECPARAM)) { retVal.add(new DataType(ref.getRefID(), ref.toAny())); } } } } return retVal.toArray(new DataType[retVal.size()]); } private boolean isAssemblyController(final SadComponentInstantiation comp) { if (comp == null) { return false; } final SoftwareAssembly sad = (SoftwareAssembly) EcoreUtil.getRootContainer(comp); if (sad.getAssemblyController() != null) { return sad.getAssemblyController().getComponentInstantiationRef().getInstantiation() == comp; } return false; } }