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); } }