/**
* 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.model.sca.util;
import gov.redhawk.model.sca.ScaDomainManager;
import gov.redhawk.model.sca.ScaModelPlugin;
import gov.redhawk.model.sca.ScaWaveform;
import gov.redhawk.model.sca.ScaWaveformFactory;
import gov.redhawk.model.sca.commands.ScaModelCommand;
import gov.redhawk.sca.util.Debug;
import java.util.concurrent.Callable;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.emf.transaction.RunnableWithResult;
import org.omg.CORBA.SystemException;
import CF.DataType;
import CF.DeviceAssignmentType;
import CF.DomainManagerPackage.ApplicationAlreadyInstalled;
import CF.DomainManagerPackage.ApplicationUninstallationError;
import CF.DomainManagerPackage.InvalidIdentifier;
import CF.LifeCyclePackage.ReleaseError;
/**
* @since 14.0
*/
public class LaunchWaveformCallable implements Callable<ScaWaveform> {
private static final Debug DEBUG = new Debug(ScaModelPlugin.ID, "launch/waveform");
private final ScaDomainManager domMgr;
private final String waveformName;
private final IPath waveformPath;
private final DeviceAssignmentType[] deviceAssn;
private final DataType[] configProps;
private final boolean autoStart;
private SubMonitor subMonitor;
public LaunchWaveformCallable(final ScaDomainManager domMgr, final String waveformName, final IPath waveformPath, final DeviceAssignmentType[] deviceAssn,
final DataType[] configProps, final boolean autoStart, IProgressMonitor monitor) {
this.domMgr = domMgr;
this.waveformName = waveformName;
this.waveformPath = waveformPath;
this.deviceAssn = deviceAssn;
this.configProps = configProps;
this.autoStart = autoStart;
subMonitor = SubMonitor.convert(monitor, "Launching Application: " + this.waveformName, IProgressMonitor.UNKNOWN);
}
@Override
public ScaWaveform call() throws Exception {
// Track whether we installed the ApplicationFactory ourselves.
ScaWaveform retVal = null;
ScaWaveformFactory factory = null;
boolean installed = false;
try {
////////////////////
// INSTALL WAVEFORM
final String profile = this.waveformPath.toPortableString();
subMonitor.subTask("Installing REDHAWK Waveform: " + profile);
while (factory == null) {
if (subMonitor.isCanceled()) {
throw new OperationCanceledException();
}
try {
factory = this.domMgr.installScaWaveformFactory(profile);
installed = true;
} catch (final ApplicationAlreadyInstalled a) {
try {
factory = ScaModelCommand.runExclusive(this.domMgr, new RunnableWithResult.Impl<ScaWaveformFactory>() {
@Override
public void run() {
for (final ScaWaveformFactory factory : LaunchWaveformCallable.this.domMgr.getWaveformFactories()) {
if (factory.getProfile().equals(profile)) {
setResult(factory);
}
}
}
});
} catch (final InterruptedException e) {
// PASS
}
}
}
subMonitor.worked(1);
if (subMonitor.isCanceled()) {
throw new OperationCanceledException();
}
Assert.isNotNull(factory, "Failed to get REDHAWK Waveform Factory");
////////////////////
// CREATE WAVEFORM
final IProgressMonitor createMonitor = subMonitor.newChild(1);
createMonitor.beginTask("Creating application: " + this.waveformName, IProgressMonitor.UNKNOWN);
retVal = factory.createWaveform(createMonitor, LaunchWaveformCallable.this.waveformName, LaunchWaveformCallable.this.configProps,
LaunchWaveformCallable.this.deviceAssn);
if (subMonitor.isCanceled()) {
throw new OperationCanceledException();
}
if (this.autoStart) {
final StartJob job = new StartJob(waveformName, retVal);
job.setUser(true);
job.schedule();
}
if (subMonitor.isCanceled()) {
throw new OperationCanceledException();
}
} finally {
// If we installed the ApplicationFactory above, uninstall it to prevent
// future conflicts if the user changes the SAD.
try {
if (subMonitor.isCanceled()) {
// the user requested a cancel...so let's release the app
if (retVal != null) {
try {
retVal.releaseObject();
} catch (final ReleaseError e) {
// PASS
}
retVal = null;
}
}
if (installed && factory != null) {
try {
this.domMgr.uninstallScaWaveformFactory(factory);
} catch (final ApplicationUninstallationError a) {
if (DEBUG.enabled) {
DEBUG.message("Failed to uninstall Waveform factory after launching a waveform.");
DEBUG.catching(a);
}
} catch (final InvalidIdentifier i) {
if (DEBUG.enabled) {
DEBUG.message("Failed to uninstall Waveform factory after launching a waveform.");
DEBUG.catching(i);
}
} catch (final SystemException e) {
if (DEBUG.enabled) {
DEBUG.message("Failed to uninstall Waveform factory after launching a waveform.");
DEBUG.catching(e);
}
}
}
} finally {
subMonitor.done();
}
}
return retVal;
}
}