package jetbrains.mps.debugger.java.runtime.breakpoints;
/*Generated by MPS */
import jetbrains.mps.debug.api.breakpoints.ILocationBreakpoint;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.jetbrains.mps.openapi.model.SNodeReference;
import jetbrains.mps.debug.api.breakpoints.BreakpointLocation;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.debugger.java.runtime.engine.events.EventsProcessor;
import com.sun.jdi.ReferenceType;
import jetbrains.mps.debugger.java.runtime.engine.RequestManager;
import com.sun.jdi.request.MethodEntryRequest;
import com.sun.jdi.request.MethodExitRequest;
import com.sun.jdi.ClassNotPreparedException;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.InternalException;
import jetbrains.mps.textgen.trace.TraceablePositionInfo;
import jetbrains.mps.debugger.java.runtime.engine.events.EventContext;
import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.Method;
import com.sun.jdi.event.MethodEntryEvent;
import com.sun.jdi.event.MethodExitEvent;
public class MethodBreakpoint extends JavaBreakpoint implements ILocationBreakpoint {
private static final Logger LOG = LogManager.getLogger(MethodBreakpoint.class);
private final SNodeReference myNode;
private BreakpointLocation myLocation;
private String myMethodName = null;
private String myJniSignature = null;
public MethodBreakpoint(SNodeReference nodePointer, Project project) {
super(project);
myNode = nodePointer;
}
public MethodBreakpoint(@NotNull SNode node, Project project) {
this(node.getReference(), project);
}
@NotNull
@Override
public BreakpointLocation getLocation() {
if (myLocation == null) {
myLocation = new BreakpointLocationUpdate(myNode, getRepository()).get();
}
return myLocation;
}
@Override
protected String getClassNameToPrepare() {
return getLocation().getTargetUnitName();
}
@NotNull
@Override
public JavaBreakpointKind getKind() {
return JavaBreakpointKind.METHOD_BREAKPOINT;
}
@Override
public String getPresentation() {
return new BreakpointPresentation(getLocation(), getRepository()).getText();
}
@Override
protected void createRequestForPreparedClass(EventsProcessor debugProcess, ReferenceType classType) {
RequestManager requestManager = debugProcess.getRequestManager();
if (!(updateMethodNameAndSignature())) {
return;
}
try {
MethodEntryRequest methodEntryRequest = requestManager.createMethodEntryRequest(this, classType);
MethodExitRequest methodExitRequest = requestManager.createMethodExitRequest(this, classType);
requestManager.enableRequest(methodEntryRequest);
requestManager.enableRequest(methodExitRequest);
} catch (ClassNotPreparedException ex) {
LOG.warn("ClassNotPreparedException: " + ex.getMessage());
// there's a chance to add a breakpoint when the class is prepared
} catch (ObjectCollectedException ex) {
LOG.warn("ObjectCollectedException: " + ex.getMessage());
} catch (InternalException ex) {
LOG.error(null, ex);
} catch (Exception ex) {
LOG.error(null, ex);
}
}
private boolean updateMethodNameAndSignature() {
if (myMethodName != null && myJniSignature != null) {
return true;
}
TraceablePositionInfo targetCodePosition = getLocation().getTargetCodePosition();
if (targetCodePosition == null) {
return false;
}
String propertyString = targetCodePosition.getPropertyString();
if (propertyString == null) {
return false;
}
// todo property string format should be described in one place
String[] split = propertyString.split("#");
if (split.length != 2) {
return false;
}
myMethodName = split[0];
myJniSignature = split[1];
return myMethodName != null && myJniSignature != null;
}
@Override
public boolean isRequestHitByEvent(EventContext context, LocatableEvent event) {
boolean result = super.isRequestHitByEvent(context, event);
if (!(result)) {
return false;
}
Method method = null;
if (event instanceof MethodEntryEvent) {
method = ((MethodEntryEvent) event).method();
} else
if (event instanceof MethodExitEvent) {
method = ((MethodExitEvent) event).method();
}
return !((method == null || !(accept(method))));
}
private boolean accept(Method method) {
return method.name().equals(myMethodName) && method.signature().equals(myJniSignature);
}
@Override
public boolean isValid() {
return super.isValid() && updateMethodNameAndSignature();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || this.getClass() != o.getClass()) {
return false;
}
return eq_spo82x_a0d0u(getLocation(), ((MethodBreakpoint) o).getLocation());
}
@Override
public int hashCode() {
return myNode.hashCode() + getKind().hashCode() * 31;
}
private static boolean eq_spo82x_a0d0u(Object a, Object b) {
return (a != null ? a.equals(b) : a == b);
}
}