package bndtools.launch.util;
import java.io.File;
import org.bndtools.api.ILogger;
import org.bndtools.api.RunListener;
import org.bndtools.api.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.debug.core.ILaunchConfiguration;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.util.tracker.ServiceTracker;
import aQute.bnd.build.Project;
import aQute.bnd.build.Run;
import aQute.bnd.build.Workspace;
import bndtools.central.Central;
import bndtools.launch.LaunchConstants;
public final class LaunchUtils {
private static final ILogger logger = Logger.getLogger(LaunchUtils.class);
private static ServiceTracker<RunListener,RunListener> runListeners;
private LaunchUtils() {}
public static IResource getTargetResource(ILaunchConfiguration configuration) throws CoreException {
String target = getTargetName(configuration);
if (target == null)
return null;
IResource targetResource = ResourcesPlugin.getWorkspace().getRoot().findMember(target);
return targetResource;
}
public static String getLaunchProjectName(IResource launchResource) {
String result;
IProject project = launchResource.getProject();
Project bnd;
try {
bnd = Central.getWorkspace().getProject(project.getName());
} catch (Exception e) {
bnd = null;
}
result = (bnd != null) ? bnd.getName() : Project.BNDCNF;
return result;
}
public static Run createRun(ILaunchConfiguration configuration) throws Exception {
IResource targetResource = getTargetResource(configuration);
if (targetResource == null) {
String target = getTargetName(configuration);
throw new IllegalArgumentException(String.format("The run descriptor '%s' could not be found.", target));
}
return createRun(targetResource);
}
public static Run createRun(IResource targetResource) throws Exception {
Run run;
Workspace ws = Central.getWorkspaceIfPresent();
if (targetResource.getType() == IResource.PROJECT) {
// This is a bnd project --> find the bnd.bnd file
IProject project = (IProject) targetResource;
if (ws == null)
throw new Exception(String.format("Cannot load Bnd project for directory %s: no Bnd workspace found", project.getLocation()));
File bndFile = project.getFile(Project.BNDFILE).getLocation().toFile();
if (bndFile == null || !bndFile.isFile())
throw new Exception(String.format("Failed to load Bnd project for directory %s: %s does not exist or is not a file.", project.getLocation(), Project.BNDFILE));
run = Run.createRun(ws, bndFile);
} else if (targetResource.getType() == IResource.FILE) {
// This is file, use directly
File file = targetResource.getLocation().toFile();
if (file == null || !file.isFile())
throw new Exception(String.format("Failed to create Bnd launch configuration: %s does not exist or is not a file.", file));
run = Run.createRun(ws, file);
} else {
throw new Exception(String.format("Cannot create a Bnd launch configuration for %s: not a project or file resource.", targetResource.getLocation()));
}
for (RunListener runListener : getRunListeners()) {
try {
runListener.create(run);
} catch (Throwable t) {
logger.logError("Error in run listener", t);
}
}
return run;
}
private static String getTargetName(ILaunchConfiguration configuration) throws CoreException {
String target = configuration.getAttribute(LaunchConstants.ATTR_LAUNCH_TARGET, (String) null);
if (target != null && target.isEmpty()) {
target = null;
}
return target;
}
public static void endRun(Run run) {
for (RunListener runListener : getRunListeners()) {
try {
runListener.end(run);
} catch (Throwable t) {
logger.logError("Error in run listener", t);
}
}
}
private static synchronized RunListener[] getRunListeners() {
if (runListeners == null) {
final BundleContext context = FrameworkUtil.getBundle(LaunchUtils.class).getBundleContext();
if (context == null) {
throw new IllegalStateException("Bundle context is null");
}
runListeners = new ServiceTracker<RunListener,RunListener>(context, RunListener.class, null);
runListeners.open();
}
return runListeners.getServices(new RunListener[0]);
}
}