package jetbrains.mps.debugger.api.ui.breakpoints;
/*Generated by MPS */
import jetbrains.mps.debugger.core.breakpoints.BreakpointsUiComponentEx;
import jetbrains.mps.debug.api.breakpoints.IBreakpoint;
import jetbrains.mps.debug.api.breakpoints.ILocationBreakpoint;
import com.intellij.openapi.components.ProjectComponent;
import jetbrains.mps.logging.Logger;
import org.apache.log4j.LogManager;
import jetbrains.mps.project.MPSProject;
import jetbrains.mps.debug.api.BreakpointManagerComponent;
import jetbrains.mps.debug.api.breakpoints.BreakpointProvidersManager;
import jetbrains.mps.debug.api.BreakpointCreatorsManager;
import jetbrains.mps.debug.api.SessionChangeListener;
import jetbrains.mps.debug.api.DebugSessionManagerComponent;
import com.intellij.openapi.fileEditor.FileEditorManager;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.application.ApplicationManager;
import java.util.Set;
import jetbrains.mps.nodeEditor.EditorComponent;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import java.util.HashSet;
import org.jetbrains.mps.openapi.module.SRepository;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.model.SNodeUtil;
import org.jetbrains.mps.openapi.model.SNodeReference;
import jetbrains.mps.ide.editor.util.EditorComponentUtil;
import java.util.List;
import jetbrains.mps.smodel.ModelAccessHelper;
import jetbrains.mps.util.Computable;
import java.util.Collections;
import jetbrains.mps.openapi.editor.cells.EditorCell;
import jetbrains.mps.debug.api.breakpoints.IBreakpointKind;
import jetbrains.mps.debug.api.breakpoints.IBreakpointsProvider;
import com.intellij.openapi.ui.Messages;
import jetbrains.mps.debugger.core.breakpoints.BreakpointIconRenderrerEx;
import jetbrains.mps.debugger.core.breakpoints.BreakpointPainterEx;
import com.intellij.openapi.project.Project;
import org.jdom.Element;
import org.jdom.Attribute;
import jetbrains.mps.debug.api.breakpoints.IBreakpointListener;
import jetbrains.mps.debug.api.AbstractDebugSession;
import jetbrains.mps.debug.api.SessionChangeAdapter;
public class BreakpointsUiComponent extends BreakpointsUiComponentEx<IBreakpoint, ILocationBreakpoint> implements ProjectComponent {
private static final Logger LOG = Logger.wrap(LogManager.getLogger(BreakpointsUiComponent.class));
private static final String BREAKPOINT_ELEMENT = "breakpoint";
private static final String KIND_TAG = "kind";
private final MPSProject myMPSProject;
private final BreakpointManagerComponent myBreakpointsManagerComponent;
private final BreakpointProvidersManager myProvidersManager;
private final BreakpointCreatorsManager myDebugInfoManager;
private final BreakpointsUiComponent.MyBreakpointManagerListener myBreakpointManagerListener = new BreakpointsUiComponent.MyBreakpointManagerListener();
private final BreakpointsUiComponent.MyBreakpointListener myBreakpointListener = new BreakpointsUiComponent.MyBreakpointListener();
private final SessionChangeListener myChangeListener = new BreakpointsUiComponent.MySessionChangeAdapter();
private final DebugSessionManagerComponent.DebugSessionListener myDebugSessionListener = new BreakpointsUiComponent.MyDebugSessionAdapter();
public BreakpointsUiComponent(MPSProject project, BreakpointManagerComponent breakpointsManagerComponent, BreakpointCreatorsManager debugInfoManager, BreakpointProvidersManager providersManager, FileEditorManager fileEditorManager) {
super(project.getProject(), fileEditorManager);
myMPSProject = project;
myBreakpointsManagerComponent = breakpointsManagerComponent;
myDebugInfoManager = debugInfoManager;
myProvidersManager = providersManager;
}
@NotNull
@Override
public String getComponentName() {
return "Breakpoints Ui Component";
}
@Override
public void initComponent() {
super.init();
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
myBreakpointsManagerComponent.setBreakpointsIO(new BreakpointsUiComponent.MyBreakpointsIO());
}
});
DebugSessionManagerComponent component = myProject.getComponent(DebugSessionManagerComponent.class);
component.addDebugSessionListener(myDebugSessionListener);
myBreakpointsManagerComponent.addChangeListener(myBreakpointManagerListener);
}
@Override
public void disposeComponent() {
myBreakpointsManagerComponent.removeChangeListener(myBreakpointManagerListener);
DebugSessionManagerComponent component = myProject.getComponent(DebugSessionManagerComponent.class);
component.removeDebugSessionListener(myDebugSessionListener);
super.dispose();
}
public void editBreakpointProperties(final ILocationBreakpoint breakpoint) {
final BreakpointsBrowserDialog breakpointsBrowserDialog = new BreakpointsBrowserDialog(myMPSProject);
breakpointsBrowserDialog.show();
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
breakpointsBrowserDialog.selectBreakpoint(breakpoint);
}
});
}
@NotNull
@Override
protected Set<ILocationBreakpoint> getBreakpointsForComponent(@NotNull final EditorComponent editorComponent) {
final Wrappers._T<Set<ILocationBreakpoint>> result = new Wrappers._T<Set<ILocationBreakpoint>>(new HashSet<ILocationBreakpoint>());
final SRepository repository = editorComponent.getEditorContext().getRepository();
repository.getModelAccess().runReadAction(new Runnable() {
public void run() {
final SNode editedNode = editorComponent.getEditedNode();
if (editedNode == null) {
return;
}
if (!(SNodeUtil.isAccessible(editedNode, repository))) {
Set<IBreakpoint> allBreakpoints = myBreakpointsManagerComponent.getAllIBreakpoints();
Set<ILocationBreakpoint> locationBreakpoints = new HashSet<ILocationBreakpoint>();
for (IBreakpoint breakpoint : allBreakpoints) {
if (breakpoint instanceof ILocationBreakpoint) {
locationBreakpoints.add((ILocationBreakpoint) breakpoint);
}
}
result.value = locationBreakpoints;
return;
}
SNode rootNode = (editedNode.getModel() == null ? null : editedNode.getContainingRoot());
if (rootNode == null) {
return;
}
final Set<ILocationBreakpoint> closeBreakpoints = myBreakpointsManagerComponent.getBreakpoints(rootNode.getReference());
for (ILocationBreakpoint locationBreakpoint : closeBreakpoints) {
SNodeReference nodePtr = locationBreakpoint.getLocation().getNodePointer();
SNode node = nodePtr.resolve(repository);
if (node != null && EditorComponentUtil.isNodeShownInTheComponent(editorComponent, node)) {
result.value.add(locationBreakpoint);
}
}
}
});
return result.value;
}
@NotNull
@Override
protected List<EditorComponent> getComponentsForBreakpoint(@NotNull final ILocationBreakpoint breakpoint) {
// reverse operation to getBreakpointsForComponent
return new ModelAccessHelper(myMPSProject.getModelAccess()).runReadAction(new Computable<List<EditorComponent>>() {
public List<EditorComponent> compute() {
SNode node = breakpoint.getLocation().getNodePointer().resolve(myMPSProject.getRepository());
if (node != null) {
return EditorComponentUtil.findComponentForNode(node, myFileEditorManager);
}
return Collections.emptyList();
}
});
}
@Override
protected EditorCell findDebuggableOrTraceableCell(EditorCell foundCell) {
EditorCell cell = findDebuggableCell(foundCell);
if (cell == null) {
cell = findTraceableCell(foundCell);
}
if (cell == null) {
return null;
}
return cell;
}
private EditorCell findDebuggableCell(EditorCell foundCell) {
EditorCell cell = foundCell;
while (cell != null) {
SNode node = cell.getSNode();
if (myDebugInfoManager.isDebuggableNode(node)) {
return cell;
}
cell = cell.getParent();
}
return null;
}
@Override
protected void toggleBreakpoint(@NotNull SNode node) {
IBreakpoint breakpoint = null;
Set<ILocationBreakpoint> mpsBreakpointSet = myBreakpointsManagerComponent.getBreakpoints(node.getContainingRoot().getReference());
for (ILocationBreakpoint mpsBreakpoint : mpsBreakpointSet) {
if (mpsBreakpoint.getLocation().getNodePointer().equals(node.getReference())) {
breakpoint = mpsBreakpoint;
break;
}
}
if (breakpoint != null) {
myBreakpointsManagerComponent.removeBreakpoint(breakpoint);
} else {
ILocationBreakpoint newBreakpoint = myDebugInfoManager.createBreakpoint(node, myProject);
if (newBreakpoint != null) {
myBreakpointsManagerComponent.addBreakpoint(newBreakpoint);
} else
if (myDebugInfoManager.isDebuggableNode(node)) {
LOG.error("Node is debuggable but created breakpoint is null.", node);
} else {
LOG.error("Trying to create breakpoint on non-debuggable node.", node);
}
}
}
public void createFromUi(IBreakpointKind kind) {
IBreakpointsProvider provider = myProvidersManager.getProvider(kind);
if (provider == null) {
Messages.showErrorDialog(myProject, "Can not create " + kind.getPresentation() + ". Provider was not found.", "Error Creating" + kind.getPresentation());
} else {
IBreakpoint breakpoint = provider.createFromUi(kind, myProject);
if (breakpoint != null) {
myBreakpointsManagerComponent.addBreakpoint(breakpoint);
}
}
}
@Override
protected BreakpointIconRenderrerEx<ILocationBreakpoint> createRenderrer(ILocationBreakpoint breakpoint, EditorComponent component) {
return new BreakpointIconRenderer(breakpoint, component);
}
@Override
protected BreakpointPainterEx<ILocationBreakpoint> createPainter(ILocationBreakpoint breakpoint) {
return new BreakpointPainter(breakpoint);
}
@Override
public void projectOpened() {
}
@Override
public void projectClosed() {
}
public static BreakpointsUiComponent getInstance(Project project) {
return project.getComponent(BreakpointsUiComponent.class);
}
private class MyBreakpointsIO implements BreakpointManagerComponent.IBreakpointsIO {
private MyBreakpointsIO() {
}
@Override
public IBreakpoint readBreakpoint(@NotNull Element element) {
String kindName = element.getAttributeValue(BreakpointsUiComponent.KIND_TAG);
IBreakpointKind kind = myProvidersManager.getKind(kindName);
if (kind == null) {
return null;
}
IBreakpointsProvider provider = myProvidersManager.getProvider(kind);
if (provider == null) {
return null;
}
IBreakpoint breakpoint = provider.loadFromState((Element) element.getChildren().get(0), kind, myProject);
if (breakpoint != null) {
breakpoint.addBreakpointListener(myBreakpointListener);
}
return breakpoint;
}
@Override
public Element writeBreakpoint(@NotNull IBreakpoint breakpoint) {
IBreakpointKind kind = breakpoint.getKind();
IBreakpointsProvider provider = myProvidersManager.getProvider(kind);
if (provider == null) {
return null;
}
Element element = provider.saveToState(breakpoint);
if (element != null) {
Element breakpointElement = new Element(BreakpointsUiComponent.BREAKPOINT_ELEMENT);
breakpointElement.setAttribute(new Attribute(BreakpointsUiComponent.KIND_TAG, kind.getName()));
breakpointElement.addContent(element);
return breakpointElement;
}
return null;
}
}
private class MyBreakpointManagerListener implements BreakpointManagerComponent.IBreakpointManagerListener {
private MyBreakpointManagerListener() {
}
@Override
public void breakpointAdded(@NotNull final IBreakpoint breakpoint) {
if (breakpoint instanceof ILocationBreakpoint) {
addLocationBreakpoint((ILocationBreakpoint) breakpoint);
}
breakpoint.addBreakpointListener(myBreakpointListener);
}
@Override
public void breakpointRemoved(@NotNull final IBreakpoint breakpoint) {
if (breakpoint instanceof ILocationBreakpoint) {
removeLocationBreakpoint((ILocationBreakpoint) breakpoint);
}
breakpoint.removeBreakpointListener(myBreakpointListener);
}
}
private class MyBreakpointListener implements IBreakpointListener {
private MyBreakpointListener() {
}
@Override
public void breakpointEnabledStateToggled(final IBreakpoint breakpoint, boolean enabled) {
if (breakpoint instanceof ILocationBreakpoint) {
for (EditorComponent editorComponent : getComponentsForBreakpoint((ILocationBreakpoint) breakpoint)) {
editorComponent.repaintExternalComponent();
}
}
}
}
private class MyDebugSessionAdapter extends DebugSessionManagerComponent.DebugSessionAdapter {
private MyDebugSessionAdapter() {
}
@Override
public void registered(AbstractDebugSession session) {
session.addChangeListener(myChangeListener);
}
@Override
public void detached(AbstractDebugSession session) {
session.removeChangeListener(myChangeListener);
}
}
private class MySessionChangeAdapter extends SessionChangeAdapter {
private MySessionChangeAdapter() {
}
@Override
public void muted(AbstractDebugSession session) {
ApplicationManager.getApplication().invokeLater((new Runnable() {
@Override
public void run() {
for (EditorComponent editorComponent : EditorComponentUtil.getAllEditorComponents(myFileEditorManager, true)) {
editorComponent.repaintExternalComponent();
}
}
}));
}
}
}