package org.dresdenocl.debug.launch;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.dresdenocl.debug.IOclDebuggable;
import org.dresdenocl.debug.OclDebugPlugin;
import org.dresdenocl.debug.OclDebugger;
import org.dresdenocl.debug.model.OclDebugProcess;
import org.dresdenocl.debug.model.OclDebugTarget;
import org.dresdenocl.debug.model.OclDebuggerListener;
import org.dresdenocl.model.IModel;
import org.dresdenocl.model.ModelAccessException;
import org.dresdenocl.modelbus.ModelBusPlugin;
import org.dresdenocl.modelinstance.IModelInstance;
import org.dresdenocl.modelinstancetype.types.IModelInstanceElement;
import org.dresdenocl.pivotmodel.Constraint;
import org.dresdenocl.pivotmodel.ConstraintKind;
import org.dresdenocl.pivotmodel.NamedElement;
import org.dresdenocl.pivotmodel.Operation;
import org.dresdenocl.pivotmodel.Type;
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.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
public class OclLaunchConfigurationDelegate extends LaunchConfigurationDelegate {
@Override
public void launch(ILaunchConfiguration configuration, String mode,
ILaunch launch, IProgressMonitor monitor) throws CoreException {
final int requestPort;
final int eventPort;
// Check preconditions
final IModel model;
final IModelInstance minstance;
final List<IModelInstanceElement> miElements;
final Collection<Constraint> constraints;
model = ModelBusPlugin.getModelRegistry().getActiveModel();
if (model == null) {
abort("No active model found.", null);
}
minstance =
ModelBusPlugin.getModelInstanceRegistry().getActiveModelInstance(model);
if (minstance == null) {
abort(String.format("No active modelinstance found for {0}", model), null);
}
miElements =
new ArrayList<IModelInstanceElement>(
minstance.getAllModelInstanceObjects());
if (miElements.size() == 0) {
abort(String.format("There are no modelinstance elements for {0}",
minstance), null);
}
Collection<Constraint> c = null;
try {
c = model.getConstraints();
if (c == null || c.size() == 0) {
abort("There are no constraints to evaluate", null);
}
} catch (ModelAccessException e) {
abort("Cannot access model", e);
} finally {
constraints = c;
}
// Check for the mode
if (mode.equals(ILaunchManager.DEBUG_MODE)) {
requestPort = findFreePort();
eventPort = findFreePort();
if (requestPort == -1 || eventPort == -1) {
// unable to find free port, abort
abort("Unable to find free port.", null);
}
// 1. run the interpreter in debug mode in own thread
final IOclDebuggable interpreter = new OclDebugger(minstance);
Thread interpreterThread = new Thread(new Runnable() {
@Override
public void run() {
interpreter.setDebugMode(true);
interpreter.setEventPort(eventPort);
for (Constraint c : constraints) {
if (c.getKind().equals(ConstraintKind.POSTCONDITION)) {
NamedElement constrainedElement =
(NamedElement) c.getConstrainedElement().get(0);
if (constrainedElement instanceof Operation) {
for (IModelInstanceElement mie : miElements) {
Type type = (Type) constrainedElement.getOwner();
if (mie.isKindOf(type)) {
ArrayList<Constraint> postConditions =
new ArrayList<Constraint>();
postConditions.add(c);
interpreter.preparePostConditions(mie,
(Operation) constrainedElement,
new IModelInstanceElement[0], postConditions);
}
// no else
}
// end for
}
// no else
}
// no else
if (c.hasStaticContext()) {
interpreter.interpretConstraint(c, null);
}
else {
for (IModelInstanceElement mie : miElements) {
interpreter.interpretConstraint(c, mie);
}
// end for
}
// end else
}
// end for
}
});
interpreterThread.start();
// 2. make debug listener attach to debugger
OclDebuggerListener listener = new OclDebuggerListener(requestPort);
listener.setDebuggable(interpreter);
new Thread(listener).start();
// 3. start debugger
OclDebugProcess process = new OclDebugProcess(launch);
OclDebugTarget target =
new OclDebugTarget(launch, process, requestPort, eventPort);
launch.addDebugTarget(target);
}
else if (mode.equals(ILaunchManager.RUN_MODE)) {
// run the interpreter in normal launch mode
// IDebugTarget target = null;
// TODO Lars: Initialize target
// launch.addDebugTarget(target);
}
else {
// Nothing has been applied
abort(String.format("Do not know what to do with {0}", mode), null);
}
}
private void abort(final String message, final Throwable e)
throws CoreException {
throw new CoreException(new Status(IStatus.ERROR, OclDebugPlugin.PLUGIN_ID,
message, e));
}
/**
* Returns a free port number on localhost, or -1 if unable to find a free
* port.
*
* @return a free port number on localhost, or -1 if unable to find a free
* port
*/
private static int findFreePort() {
ServerSocket socket = null;
try {
socket = new ServerSocket(0);
return socket.getLocalPort();
} catch (IOException e) {
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
}
}
}
return -1;
}
}