CHE-6545: Add condition for breakpoints (#6763) (#6786)

6.19.x
Anatoliy Bazko 2017-10-18 11:46:00 +00:00 committed by GitHub
parent 6620c0c85b
commit d3278187fb
44 changed files with 1039 additions and 158 deletions

View File

@ -28,4 +28,7 @@ public interface BreakpointManager extends BreakpointManagerObservable {
/** Removes all breakpoints. */
void deleteAllBreakpoints();
/** Updates the given breakpoint. */
void update(Breakpoint breakpoint);
}

View File

@ -10,20 +10,21 @@
*/
package org.eclipse.che.ide.api.debug;
import org.eclipse.che.api.debug.shared.model.Breakpoint;
import org.eclipse.che.ide.api.resources.VirtualFile;
/** Component that handles breakpoints display. */
public interface BreakpointRenderer {
/**
* Add a breakpoint mark in the gutter on the given line.
* Adds inactive breakpoint mark in the given line.
*
* @param lineNumber the line where the breakpoint is set
*/
void addBreakpointMark(int lineNumber);
/**
* Add a breakpoint mark in the gutter on the given line.
* Adds inactive breakpoint mark in the given line.
*
* @param lineNumber the line where the breakpoint is set
* @param action to line numbering changes
@ -31,8 +32,18 @@ public interface BreakpointRenderer {
void addBreakpointMark(int lineNumber, LineChangeAction action);
/**
* Removes the breakpoint mark in the gutter on the given line.<br>
* Does nothing if there is no breakpoint on this line.
* Adds a breakpoint mark of the given breakpoint. If the mark exists then it will be changed
* depending on {@code active} state and {@link Breakpoint#getCondition()}.
*
* @param breakpoint the given breakpoint
* @param active indicates if breakpoint is active or isn't
* @param action to line numbering changes
*/
default void setBreakpointMark(Breakpoint breakpoint, boolean active, LineChangeAction action) {}
/**
* Removes the breakpoint mark in the gutter on the given line. Does nothing if there is no
* breakpoint on this line.
*
* @param lineNumber the line where the breakpoint is set
*/
@ -42,8 +53,7 @@ public interface BreakpointRenderer {
void clearBreakpointMarks();
/**
* Changes appearance of the breakpoint on the line to active/inactive.<br>
* Does nothing if there is no breakpoint of this line.
* Adds {@code active} breakpoint mark in the given line.
*
* @param lineNumber the line where the breakpoint is set
*/

View File

@ -49,6 +49,13 @@ public interface BreakpointStorage {
*/
void deleteAll(List<Breakpoint> breakpoints);
/**
* Updates breakpoint.
*
* @param breakpoint
*/
void update(Breakpoint breakpoint);
/** Clears storage. */
void clear();

View File

@ -134,7 +134,7 @@ public class BreakpointManagerImpl
Debugger debugger = debuggerManager.getActiveDebugger();
if (debugger != null) {
debugger.deleteBreakpoint(activeFile, breakpoint);
debugger.deleteBreakpoint(breakpoint);
}
}
@ -147,8 +147,7 @@ public class BreakpointManagerImpl
final BreakpointRenderer renderer = getBreakpointRendererForFile(file.getLocation().toString());
if (renderer != null) {
renderer.addBreakpointMark(
breakpoint.getLocation().getLineNumber() - 1, BreakpointManagerImpl.this::onLineChange);
renderer.setBreakpointMark(breakpoint, false, BreakpointManagerImpl.this::onLineChange);
}
for (BreakpointManagerObserver observer : observers) {
@ -157,7 +156,7 @@ public class BreakpointManagerImpl
Debugger debugger = debuggerManager.getActiveDebugger();
if (debugger != null) {
debugger.addBreakpoint(file, breakpoint);
debugger.addBreakpoint(breakpoint);
}
}
@ -218,6 +217,23 @@ public class BreakpointManagerImpl
}
}
@Override
public void update(Breakpoint breakpoint) {
breakpointStorage.update(breakpoint);
BreakpointRenderer renderer =
getBreakpointRendererForFile(breakpoint.getLocation().getTarget());
if (renderer != null) {
renderer.setBreakpointMark(breakpoint, false, BreakpointManagerImpl.this::onLineChange);
}
Debugger debugger = debuggerManager.getActiveDebugger();
if (debugger != null) {
debugger.deleteBreakpoint(breakpoint);
debugger.addBreakpoint(breakpoint);
}
}
private void deleteBreakpoints(String parentPath) {
List<Breakpoint> breakpoints2delete =
breakpointStorage
@ -417,9 +433,8 @@ public class BreakpointManagerImpl
.getByPath(filePath)
.forEach(
breakpoint ->
renderer.addBreakpointMark(
breakpoint.getLocation().getLineNumber() - 1,
BreakpointManagerImpl.this::onLineChange));
renderer.setBreakpointMark(
breakpoint, false, BreakpointManagerImpl.this::onLineChange));
Debugger debugger = debuggerManager.getActiveDebugger();
if (debugger != null) {
@ -428,8 +443,10 @@ public class BreakpointManagerImpl
.then(
breakpoints -> {
for (Breakpoint breakpoint : breakpoints) {
renderer.setBreakpointActive(
breakpoint.getLocation().getLineNumber() - 1, true);
if (breakpoint.getLocation().getTarget().equals(filePath)) {
renderer.setBreakpointMark(
breakpoint, true, BreakpointManagerImpl.this::onLineChange);
}
}
});
}
@ -457,7 +474,8 @@ public class BreakpointManagerImpl
BreakpointRenderer renderer =
getBreakpointRendererForFile(breakpoint.getLocation().getTarget());
if (renderer != null) {
renderer.setBreakpointActive(breakpoint.getLocation().getLineNumber() - 1, false);
renderer.setBreakpointMark(
breakpoint, false, BreakpointManagerImpl.this::onLineChange);
}
});
@ -476,7 +494,8 @@ public class BreakpointManagerImpl
BreakpointRenderer renderer =
getBreakpointRendererForFile(breakpoint.getLocation().getTarget());
if (renderer != null) {
renderer.setBreakpointActive(breakpoint.getLocation().getLineNumber() - 1, true);
renderer.setBreakpointMark(
breakpoint, true, BreakpointManagerImpl.this::onLineChange);
}
});
}

View File

@ -12,13 +12,14 @@ package org.eclipse.che.ide.debug;
import static org.eclipse.che.ide.api.editor.gutter.Gutters.BREAKPOINTS_GUTTER;
import com.google.common.base.Strings;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import elemental.dom.Element;
import org.eclipse.che.api.debug.shared.model.Breakpoint;
import org.eclipse.che.ide.api.debug.BreakpointRenderer;
import org.eclipse.che.ide.api.editor.document.Document;
import org.eclipse.che.ide.api.editor.gutter.Gutter;
import org.eclipse.che.ide.api.editor.gutter.Gutter.LineNumberingChangeCallback;
import org.eclipse.che.ide.api.editor.texteditor.EditorResources;
import org.eclipse.che.ide.api.editor.texteditor.LineStyler;
import org.eclipse.che.ide.util.dom.Elements;
@ -42,7 +43,9 @@ public class BreakpointRendererImpl implements BreakpointRenderer {
private Document document;
private Element activeBreakpointMark;
private Element activeConditionBreakpointMark;
private Element inactiveBreakpointMark;
private Element inactiveConditionBreakpointMark;
@AssistedInject
public BreakpointRendererImpl(
@ -63,26 +66,57 @@ public class BreakpointRendererImpl implements BreakpointRenderer {
}
@Override
public void addBreakpointMark(final int lineNumber) {
public void addBreakpointMark(int lineNumber) {
addBreakpointMark(lineNumber, (file, firstLine, linesAdded, linesRemoved) -> {});
}
@Override
public void addBreakpointMark(int lineNumber, LineChangeAction action) {
if (hasGutter != null) {
this.hasGutter.addGutterItem(lineNumber, BREAKPOINTS_GUTTER, inactiveBreakpointMark);
Element newElement = inactiveBreakpointMark;
Element existedElement = hasGutter.getGutterItem(lineNumber, BREAKPOINTS_GUTTER);
if (existedElement != null) {
hasGutter.setGutterItem(lineNumber, BREAKPOINTS_GUTTER, newElement);
} else {
hasGutter.addGutterItem(
lineNumber,
BREAKPOINTS_GUTTER,
newElement,
(fromLine, linesRemoved, linesAdded) ->
action.onLineChange(document.getFile(), fromLine, linesAdded, linesRemoved));
}
}
}
@Override
public void addBreakpointMark(final int lineNumber, final LineChangeAction action) {
public void setBreakpointMark(
final Breakpoint breakpoint, final boolean active, final LineChangeAction action) {
if (hasGutter != null) {
this.hasGutter.addGutterItem(
lineNumber,
BREAKPOINTS_GUTTER,
inactiveBreakpointMark,
new LineNumberingChangeCallback() {
@Override
public void onLineNumberingChange(
final int fromLine, final int linesRemoved, final int linesAdded) {
action.onLineChange(document.getFile(), fromLine, linesAdded, linesRemoved);
}
});
int lineNumber = breakpoint.getLocation().getLineNumber() - 1;
boolean hasCondition = !Strings.isNullOrEmpty(breakpoint.getCondition());
Element newElement =
active
? (hasCondition ? activeConditionBreakpointMark : activeBreakpointMark)
: (hasCondition ? inactiveConditionBreakpointMark : inactiveBreakpointMark);
if (hasCondition) {
newElement.setTitle("Condition: " + breakpoint.getCondition());
}
Element existedElement = hasGutter.getGutterItem(lineNumber, BREAKPOINTS_GUTTER);
if (existedElement != null) {
hasGutter.setGutterItem(lineNumber, BREAKPOINTS_GUTTER, newElement);
} else {
hasGutter.addGutterItem(
lineNumber,
BREAKPOINTS_GUTTER,
newElement,
(fromLine, linesRemoved, linesAdded) ->
action.onLineChange(document.getFile(), fromLine, linesAdded, linesRemoved));
}
}
}
@ -101,12 +135,11 @@ public class BreakpointRendererImpl implements BreakpointRenderer {
}
@Override
public void setBreakpointActive(final int lineNumber, final boolean active) {
public void setBreakpointActive(int lineNumber, boolean active) {
if (hasGutter != null) {
final Element mark = this.hasGutter.getGutterItem(lineNumber, BREAKPOINTS_GUTTER);
if (mark != null) {
Element element = active ? activeBreakpointMark : inactiveBreakpointMark;
this.hasGutter.setGutterItem(lineNumber, BREAKPOINTS_GUTTER, element);
Element existedElement = hasGutter.getGutterItem(lineNumber, BREAKPOINTS_GUTTER);
if (existedElement != null) {
hasGutter.setGutterItem(lineNumber, BREAKPOINTS_GUTTER, activeBreakpointMark);
}
}
}
@ -123,7 +156,11 @@ public class BreakpointRendererImpl implements BreakpointRenderer {
private void initBreakpointMarks() {
BreakpointResources.Css css = breakpointResources.getCss();
activeBreakpointMark = Elements.createDivElement(css.breakpoint(), css.active());
activeConditionBreakpointMark =
Elements.createDivElement(css.breakpoint(), css.active(), css.condition());
inactiveBreakpointMark = Elements.createDivElement(css.breakpoint(), css.inactive());
inactiveConditionBreakpointMark =
Elements.createDivElement(css.breakpoint(), css.inactive(), css.condition());
}
@Override

View File

@ -27,6 +27,9 @@ public interface BreakpointResources extends ClientBundle {
/** Returns the CSS class name for inactive breakpoint mark */
String inactive();
/** Returns the CSS class name for condition breakpoint mark */
String condition();
String breakpoint();
}
}

View File

@ -84,25 +84,31 @@ public class BreakpointStorageImpl implements BreakpointStorage {
@Override
public void delete(final Breakpoint breakpoint) {
breakpoints.removeIf(
b ->
b.getLocation().getLineNumber() == breakpoint.getLocation().getLineNumber()
&& b.getLocation().getTarget().equals(breakpoint.getLocation().getTarget()));
breakpoints.removeIf(b -> isSameBreakpointLocation(breakpoint, b));
preserve();
}
@Override
public void deleteAll(final List<Breakpoint> breakpoints) {
for (Breakpoint breakpoint : breakpoints) {
breakpoints.removeIf(
b ->
b.getLocation().getLineNumber() == breakpoint.getLocation().getLineNumber()
&& b.getLocation().getTarget().equals(breakpoint.getLocation().getTarget()));
breakpoints.removeIf(b -> isSameBreakpointLocation(breakpoint, b));
}
preserve();
}
@Override
public void update(Breakpoint breakpoint) {
breakpoints.removeIf(b -> isSameBreakpointLocation(breakpoint, b));
breakpoints.add(breakpoint);
preserve();
}
private boolean isSameBreakpointLocation(Breakpoint b1, Breakpoint b2) {
return b2.getLocation().getLineNumber() == b1.getLocation().getLineNumber()
&& b2.getLocation().getTarget().equals(b1.getLocation().getTarget());
}
@Override
public void clear() {
breakpoints.clear();
@ -189,7 +195,8 @@ public class BreakpointStorageImpl implements BreakpointStorage {
.withTarget(location.getTarget())
.withLineNumber(location.getLineNumber())
.withExternalResourceId(location.getExternalResourceId())
.withExternalResource(location.isExternalResource());
.withExternalResource(location.isExternalResource())
.withResourceProjectPath(location.getResourceProjectPath());
return dtoFactory
.createDto(BreakpointDto.class)

View File

@ -39,18 +39,16 @@ public interface Debugger extends DebuggerObservable {
/**
* Adds new breakpoint.
*
* @param file the file where breakpoint will be added
* @param breakpoint the breakpoint to add
*/
void addBreakpoint(VirtualFile file, Breakpoint breakpoint);
void addBreakpoint(Breakpoint breakpoint);
/**
* Deletes the given breakpoint on server.
*
* @param file the file where breakpoint will be removed from
* @param breakpoint the breakpoint to delete
*/
void deleteBreakpoint(VirtualFile file, Breakpoint breakpoint);
void deleteBreakpoint(Breakpoint breakpoint);
/** Deletes all breakpoints. */
void deleteAllBreakpoints();

View File

@ -10,53 +10,48 @@
*/
@external *;
.breakpoint:before {
content: "";
position: absolute;
top: 0;
left: -16px;
right: -13px;
height: 15px;
}
.breakpoint:after {
content: "";
position: absolute;
right: -19px;
z-index: 1;
width: 0;
height: 0;
border-bottom: 7px solid transparent;
border-top: 8px solid transparent;
}
.breakpoint {
position: relative;
font-family: "DejaVu Sans Mono", alternativeFontFamily;
font-size: 11px;
color: editorGutterLineNumberColor;
line-height: 15px;
}
.breakpoint.inactive:before {
background-color: rgba(144, 144, 144, 0.4);
}
.breakpoint.inactive:after {
border-left: 8px solid rgba(144, 144, 144, 0.4);
border-radius: 3px;
line-height: 13px;
font-size: fontSize;
border: 1px solid editorGutterLineNumberBackgroundColor;
box-sizing: border-box;
}
.breakpoint.inactive {
background-color: rgba(144, 144, 144, 0.4);
}
.breakpoint.active:before {
background-color: rgba(78, 171, 255, 0.4);
.breakpoint.inactive.condition {
background-color: rgba(144, 144, 144, 0.4);
}
.breakpoint.active:after {
border-left: 8px solid rgba(78, 171, 255, 0.4);
.breakpoint.inactive.condition:after {
content: "?";
position: absolute;
bottom: 0px;
left: 0px;
line-height: 7px;
font-size: 7px;
}
.breakpoint.active {
background-color: rgba(78, 171, 255, 0.4);
}
.breakpoint.active.condition {
background-color: rgba(78, 171, 255, 0.4);
}
.breakpoint.active.condition:after {
content: "?";
position: absolute;
bottom: 0px;
left: 0px;
line-height: 7px;
font-size: 7px;
}

View File

@ -171,6 +171,7 @@ public class OrionBreakpointRuler implements Gutter {
annotation.setType(CHE_BREAKPOINT);
annotation.setStart(lineStart);
annotation.setEnd(lineStart);
annotation.setTitle(element.getTitle());
return annotation;
}

View File

@ -131,7 +131,9 @@
font-family: "DejaVu Sans Mono", alternativeFontFamily;
font-size: 11px;
color: editorGutterLineNumberColor;
line-height: 15px;
line-height: 13px;
border: 1px solid editorGutterLineNumberBackgroundColor;
box-sizing: border-box;
}
.orionCodenvy .rulerZoomWindow {

View File

@ -23,6 +23,7 @@ import com.google.gwt.user.client.ui.Widget;
import elemental.dom.Element;
import elemental.events.Event;
import elemental.events.EventListener;
import elemental.events.MouseEvent;
import elemental.js.dom.JsElement;
import java.util.ArrayList;
import java.util.List;
@ -95,18 +96,11 @@ public class SimpleList<M> extends UiComponent<SimpleList.View> implements IsWid
/** Receives events fired on items in the list. */
public interface ListEventDelegate<M> {
void onListItemClicked(Element listItemBase, M itemData);
default void onListItemClicked(Element listItemBase, M itemData) {}
void onListItemDoubleClicked(Element listItemBase, M itemData);
}
default void onListItemDoubleClicked(Element listItemBase, M itemData) {}
/** A {@link ListEventDelegate} which performs no action. */
public static class NoOpListEventDelegate<M> implements ListEventDelegate<M> {
@Override
public void onListItemClicked(Element listItemBase, M itemData) {}
@Override
public void onListItemDoubleClicked(Element listItemBase, M itemData) {}
default void onListItemContextMenu(int clientX, int clientY, M itemData) {}
}
/** Item style selectors for a simple list item. */
@ -442,6 +436,32 @@ public class SimpleList<M> extends UiComponent<SimpleList.View> implements IsWid
}
},
false);
getView()
.addEventListener(
Event.CONTEXTMENU,
new EventListener() {
@Override
public void handleEvent(Event evt) {
MouseEvent mouseEvt = (MouseEvent) evt;
Element listItemElem =
CssUtils.getAncestorOrSelfWithClassName(
(Element) evt.getTarget(), css.listItem());
if (listItemElem == null) {
Log.warn(
SimpleList.class,
"Unable to find an ancestor that was a list item for a click on: ",
evt.getTarget());
return;
}
ListItem<M> listItem = ListItem.cast(listItemElem);
eventDelegate.onListItemContextMenu(
mouseEvt.getClientX(), mouseEvt.getClientY(), listItem.getData());
}
},
false);
}
public M get(int i) {

View File

@ -39,6 +39,8 @@ import org.eclipse.che.plugin.debugger.ide.actions.StepOverAction;
import org.eclipse.che.plugin.debugger.ide.actions.SuspendAction;
import org.eclipse.che.plugin.debugger.ide.configuration.DebugConfigurationsGroup;
import org.eclipse.che.plugin.debugger.ide.debug.DebuggerPresenter;
import org.eclipse.che.plugin.debugger.ide.debug.breakpoint.BreakpointActionGroup;
import org.eclipse.che.plugin.debugger.ide.debug.breakpoint.BreakpointConfigurationAction;
/**
* Extension allows debug applications.
@ -64,6 +66,10 @@ public class DebuggerExtension {
public static final String EVALUATE_EXPRESSION_ID = "evaluateExpression";
public static final String CHANGE_VARIABLE_VALUE_ID = "changeVariableValue";
public static final String SHOW_HIDE_DEBUGGER_PANEL_ID = "showHideDebuggerPanel";
public static final String BREAKPOINT_CONFIGURATION_ID = "breakpointSettings";
public static final String BREAKPOINT_CONTEXT_MENU = "breakpointContextMenu";
public static final String BREAKPOINT = "breakpoint";
@Inject
public DebuggerExtension(
@ -82,9 +88,11 @@ public class DebuggerExtension {
ChangeVariableValueAction changeVariableValueAction,
ShowHideDebuggerPanelAction showHideDebuggerPanelAction,
EditConfigurationsAction editConfigurationsAction,
BreakpointConfigurationAction breakpointConfigurationAction,
DebugConfigurationsGroup configurationsGroup,
DebuggerPresenter debuggerPresenter,
KeyBindingAgent keyBinding) {
KeyBindingAgent keyBinding,
BreakpointActionGroup breakpointActionGroup) {
debuggerResources.getCss().ensureInjected();
final DefaultActionGroup runMenu = (DefaultActionGroup) actionManager.getAction(GROUP_RUN);
@ -101,6 +109,7 @@ public class DebuggerExtension {
actionManager.registerAction(EVALUATE_EXPRESSION_ID, evaluateExpressionAction);
actionManager.registerAction(CHANGE_VARIABLE_VALUE_ID, changeVariableValueAction);
actionManager.registerAction(SHOW_HIDE_DEBUGGER_PANEL_ID, showHideDebuggerPanelAction);
actionManager.registerAction(BREAKPOINT_CONFIGURATION_ID, breakpointConfigurationAction);
// create group for selecting (changing) debug configurations
final DefaultActionGroup debugActionGroup =
@ -109,6 +118,10 @@ public class DebuggerExtension {
debugActionGroup.addSeparator();
debugActionGroup.add(configurationsGroup);
// breakpoint context menu
breakpointActionGroup.add(breakpointConfigurationAction);
actionManager.registerAction(BREAKPOINT_CONTEXT_MENU, breakpointActionGroup);
// add actions in main menu
runMenu.addSeparator();
runMenu.add(debugActionGroup, LAST);

View File

@ -66,6 +66,9 @@ public interface DebuggerLocalizationConstant extends com.google.gwt.i18n.client
@Key("showHideDebuggerPanel")
String showHideDebuggerPanel();
@Key("breakpointConfiguration")
String breakpointConfiguration();
/* actions descriptions */
@Key("editDebugConfigurationsActionDescription")
String editDebugConfigurationsActionDescription();
@ -103,6 +106,9 @@ public interface DebuggerLocalizationConstant extends com.google.gwt.i18n.client
@Key("showHideDebuggerPanelDescription")
String showHideDebuggerPanelDescription();
@Key("breakpointConfigurationDescription")
String breakpointConfigurationDescription();
/* messages */
@Key("debugger.connecting.title")
String debuggerConnectingTitle(String address);
@ -128,6 +134,10 @@ public interface DebuggerLocalizationConstant extends com.google.gwt.i18n.client
@Key("failed.to.get.variable.value.title")
String failedToGetVariableValueTitle();
/* ChangeValueView */
@Key("view.breakpoint.configuration.title")
String breakpointConfigurationTitle();
/* ChangeValueView */
@Key("view.changeValue.title")
String changeValueViewTitle();
@ -202,4 +212,14 @@ public interface DebuggerLocalizationConstant extends com.google.gwt.i18n.client
@Key("debugger.frames.title")
String debuggerFramesTitle();
/* Breakpoint Configuration */
@Key("view.breakpointConfiguration.condition")
String viewBreakpointConfigurationCondition();
@Key("view.breakpointConfiguration.hitCount")
String viewBreakpointConfigurationHitCount();
@Key("view.breakpointConfiguration.applyButton")
String viewBreakpointConfigurationApplyButton();
}

View File

@ -352,7 +352,7 @@ public abstract class AbstractDebugger implements Debugger, DebuggerObservable {
}
@Override
public void addBreakpoint(final VirtualFile file, final Breakpoint breakpoint) {
public void addBreakpoint(final Breakpoint breakpoint) {
if (isConnected()) {
Location location = breakpoint.getLocation();
@ -362,7 +362,11 @@ public abstract class AbstractDebugger implements Debugger, DebuggerObservable {
locationDto.setResourceProjectPath(location.getResourceProjectPath());
BreakpointDto breakpointDto =
dtoFactory.createDto(BreakpointDto.class).withLocation(locationDto).withEnabled(true);
dtoFactory
.createDto(BreakpointDto.class)
.withLocation(locationDto)
.withEnabled(true)
.withCondition(breakpoint.getCondition());
Promise<Void> promise = service.addBreakpoint(debugSessionDto.getId(), breakpointDto);
promise
@ -380,7 +384,7 @@ public abstract class AbstractDebugger implements Debugger, DebuggerObservable {
}
@Override
public void deleteBreakpoint(final VirtualFile file, final Breakpoint breakpoint) {
public void deleteBreakpoint(final Breakpoint breakpoint) {
if (!isConnected()) {
return;
}
@ -489,6 +493,7 @@ public abstract class AbstractDebugger implements Debugger, DebuggerObservable {
BreakpointDto breakpointDto = dtoFactory.createDto(BreakpointDto.class);
breakpointDto.setLocation(locationDto);
breakpointDto.setEnabled(true);
breakpointDto.setCondition(breakpoint.getCondition());
breakpoints.add(breakpointDto);
}

View File

@ -17,6 +17,7 @@ import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAI
import static org.eclipse.che.ide.api.notification.StatusNotification.Status.PROGRESS;
import static org.eclipse.che.ide.api.notification.StatusNotification.Status.SUCCESS;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.IsWidget;
@ -51,6 +52,7 @@ import org.eclipse.che.ide.ui.toolbar.ToolbarPresenter;
import org.eclipse.che.ide.util.loging.Log;
import org.eclipse.che.plugin.debugger.ide.DebuggerLocalizationConstant;
import org.eclipse.che.plugin.debugger.ide.DebuggerResources;
import org.eclipse.che.plugin.debugger.ide.debug.breakpoint.BreakpointContextMenuFactory;
import org.vectomatic.dom.svg.ui.SVGResource;
/**
@ -77,6 +79,7 @@ public class DebuggerPresenter extends BasePresenter
private final DebuggerManager debuggerManager;
private final WorkspaceAgent workspaceAgent;
private final DebuggerResourceHandlerFactory resourceHandlerManager;
private final BreakpointContextMenuFactory breakpointContextMenuFactory;
private List<Variable> variables;
private List<? extends ThreadState> threadDump;
@ -93,7 +96,8 @@ public class DebuggerPresenter extends BasePresenter
final @DebuggerToolbar ToolbarPresenter debuggerToolbar,
final DebuggerManager debuggerManager,
final WorkspaceAgent workspaceAgent,
final DebuggerResourceHandlerFactory resourceHandlerManager) {
final DebuggerResourceHandlerFactory resourceHandlerManager,
final BreakpointContextMenuFactory breakpointContextMenuFactory) {
this.view = view;
this.debuggerResources = debuggerResources;
this.debuggerToolbar = debuggerToolbar;
@ -104,6 +108,7 @@ public class DebuggerPresenter extends BasePresenter
this.view.setTitle(TITLE);
this.constant = constant;
this.breakpointManager = breakpointManager;
this.breakpointContextMenuFactory = breakpointContextMenuFactory;
this.notificationManager = notificationManager;
this.addRule(ProjectPerspective.PROJECT_PERSPECTIVE_ID);
@ -417,4 +422,11 @@ public class DebuggerPresenter extends BasePresenter
public boolean isDebuggerPanelOpened() {
return partStack.getActivePart() == this;
}
@Override
public void onBreakpointContextMenu(int clientX, int clientY, Breakpoint breakpoint) {
Scheduler.get()
.scheduleDeferred(
() -> breakpointContextMenuFactory.newContextMenu(breakpoint).show(clientX, clientY));
}
}

View File

@ -50,6 +50,9 @@ public interface DebuggerView extends View<DebuggerView.ActionDelegate> {
* @param frameIndex the frame index inside a thread
*/
void onSelectedFrame(int frameIndex);
/** Breakpoint context menu is invoked. */
void onBreakpointContextMenu(int clientX, int clientY, Breakpoint breakpoint);
}
/**

View File

@ -158,7 +158,6 @@ public class DebuggerViewImpl extends BaseView<DebuggerView.ActionDelegate>
@Override
public void onKeyboard(@NotNull KeyboardEvent event) {}
});
this.variablesPanel.add(variables);
}
@ -294,7 +293,10 @@ public class DebuggerViewImpl extends BaseView<DebuggerView.ActionDelegate>
breakpoints.getSelectionModel().setSelectedItem(itemData);
}
public void onListItemDoubleClicked(Element listItemBase, Breakpoint itemData) {}
@Override
public void onListItemContextMenu(int clientX, int clientY, Breakpoint itemData) {
delegate.onBreakpointContextMenu(clientX, clientY, itemData);
}
};
return SimpleList.create(
@ -314,8 +316,6 @@ public class DebuggerViewImpl extends BaseView<DebuggerView.ActionDelegate>
frames.getSelectionModel().setSelectedItem(itemData);
delegate.onSelectedFrame(frames.getSelectionModel().getSelectedIndex());
}
public void onListItemDoubleClicked(Element listItemBase, StackFrameDump itemData) {}
};
return SimpleList.create(

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.debugger.ide.debug.breakpoint;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.che.ide.api.action.ActionManager;
import org.eclipse.che.ide.api.action.DefaultActionGroup;
/**
* Groups actions that can be applied upon a breakpoint.
*
* @author Anatolii Bazko
*/
@Singleton
public class BreakpointActionGroup extends DefaultActionGroup {
@Inject
public BreakpointActionGroup(ActionManager actionManager) {
super("breakpointConfiguration", false, actionManager);
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.debugger.ide.debug.breakpoint;
import static org.eclipse.che.ide.workspace.perspectives.project.ProjectPerspective.PROJECT_PERSPECTIVE_ID;
import static org.eclipse.che.plugin.debugger.ide.DebuggerExtension.BREAKPOINT;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.Collections;
import org.eclipse.che.api.debug.shared.model.Breakpoint;
import org.eclipse.che.ide.api.action.AbstractPerspectiveAction;
import org.eclipse.che.ide.api.action.ActionEvent;
import org.eclipse.che.plugin.debugger.ide.DebuggerLocalizationConstant;
/**
* Actions allows to configure breakpoint.
*
* @author Mykola Morhun
*/
@Singleton
public class BreakpointConfigurationAction extends AbstractPerspectiveAction {
private final BreakpointConfigurationPresenter breakpointConfigurationPresenter;
@Inject
public BreakpointConfigurationAction(
DebuggerLocalizationConstant locale,
BreakpointConfigurationPresenter breakpointConfigurationPresenter) {
super(
Collections.singletonList(PROJECT_PERSPECTIVE_ID),
locale.breakpointConfiguration(),
locale.breakpointConfiguration(),
null,
null);
this.breakpointConfigurationPresenter = breakpointConfigurationPresenter;
}
@Override
public void actionPerformed(ActionEvent e) {
Breakpoint breakpoint = (Breakpoint) getTemplatePresentation().getClientProperty(BREAKPOINT);
breakpointConfigurationPresenter.showDialog(breakpoint);
}
@Override
public void updateInPerspective(ActionEvent event) {
event.getPresentation().setEnabled(true);
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.debugger.ide.debug.breakpoint;
import com.google.common.base.Strings;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.che.api.debug.shared.model.Breakpoint;
import org.eclipse.che.ide.api.debug.BreakpointManager;
/** @author Anatolii Bazko */
@Singleton
public class BreakpointConfigurationPresenter
implements BreakpointConfigurationView.ActionDelegate {
private final BreakpointConfigurationView view;
private final BreakpointManager breakpointManager;
private Breakpoint breakpoint;
@Inject
public BreakpointConfigurationPresenter(
BreakpointConfigurationView view, BreakpointManager breakpointManager) {
this.view = view;
this.breakpointManager = breakpointManager;
this.view.setDelegate(this);
}
public void showDialog(Breakpoint breakpoint) {
this.breakpoint = breakpoint;
view.setBreakpoint(breakpoint);
view.showDialog();
}
@Override
public void onApplyClicked() {
view.close();
breakpoint.setCondition(
Strings.isNullOrEmpty(view.getBreakpointCondition())
? null
: view.getBreakpointCondition());
breakpointManager.update(breakpoint);
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.debugger.ide.debug.breakpoint;
import org.eclipse.che.api.debug.shared.model.Breakpoint;
import org.eclipse.che.ide.api.mvp.View;
/**
* Provides methods which allow to change view representation of breakpoint configuration window.
*
* @author Anatolii Bazko
*/
public interface BreakpointConfigurationView
extends View<BreakpointConfigurationView.ActionDelegate> {
interface ActionDelegate {
/** Apply changes. */
void onApplyClicked();
}
void showDialog();
void close();
void setBreakpoint(Breakpoint breakpoint);
String getBreakpointCondition();
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.debugger.ide.debug.breakpoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.che.api.debug.shared.model.Breakpoint;
import org.eclipse.che.api.debug.shared.model.Location;
import org.eclipse.che.ide.resource.Path;
import org.eclipse.che.ide.ui.window.Window;
import org.eclipse.che.plugin.debugger.ide.DebuggerLocalizationConstant;
/** @author Anatolii Bazko */
@Singleton
public class BreakpointConfigurationViewImpl extends Window implements BreakpointConfigurationView {
interface BreakpointConfigurationViewImplUiBinder
extends UiBinder<Widget, BreakpointConfigurationViewImpl> {}
private static BreakpointConfigurationViewImpl.BreakpointConfigurationViewImplUiBinder uiBinder =
GWT.create(BreakpointConfigurationViewImpl.BreakpointConfigurationViewImplUiBinder.class);
@UiField Label breakpointLocation;
@UiField TextArea breakpointCondition;
private final Button applyButton;
private ActionDelegate delegate;
@Inject
public BreakpointConfigurationViewImpl(DebuggerLocalizationConstant locale) {
Widget widget = uiBinder.createAndBindUi(this);
this.setWidget(widget);
this.setTitle(locale.breakpointConfigurationTitle());
applyButton =
createButton(
locale.viewBreakpointConfigurationApplyButton(),
UIObject.DEBUG_ID_PREFIX + "apply-btn",
clickEvent -> delegate.onApplyClicked());
ensureDebugId("breakpoint-configuration-window");
addButtonToFooter(applyButton);
}
@Override
public void setDelegate(ActionDelegate delegate) {
this.delegate = delegate;
}
@Override
public void showDialog() {
this.show();
breakpointCondition.setFocus(true);
}
@Override
public void close() {
this.hide();
}
@Override
public void setBreakpoint(Breakpoint breakpoint) {
Location location = breakpoint.getLocation();
StringBuilder labelText = new StringBuilder();
labelText
.append(Path.valueOf(location.getTarget()).lastSegment())
.append(":")
.append(location.getLineNumber());
breakpointLocation.setText(labelText.toString());
if (breakpoint.getCondition() != null) {
breakpointCondition.setText(breakpoint.getCondition());
} else {
breakpointCondition.setText("");
}
}
@Override
public String getBreakpointCondition() {
return breakpointCondition.getText();
}
}

View File

@ -0,0 +1,36 @@
<!--
Copyright (c) 2012-2017 Red Hat, Inc.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:with field='locale' type='org.eclipse.che.plugin.debugger.ide.DebuggerLocalizationConstant'/>
<ui:with field='coreRes' type='org.eclipse.che.ide.Resources'/>
<ui:style>
.location {
font-weight: bold;
}
</ui:style>
<g:DockLayoutPanel unit="PX" width="400PX" height="150PX" debugId="breakpoint-configuration-panel">
<g:north size="20">
<g:FlowPanel>
<g:Label ui:field="breakpointLocation" width="100%" debugId="breakpoint-location-label" addStyleNames="{style.location}"/>
</g:FlowPanel>
</g:north>
<g:center>
<g:FlowPanel>
<g:Label text="{locale.viewBreakpointConfigurationCondition}"/>
<g:TextArea ui:field="breakpointCondition" width="100%" height="100%" debugId="breakpoint-condition-text"/>
</g:FlowPanel>
</g:center>
</g:DockLayoutPanel>
</ui:UiBinder>

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.debugger.ide.debug.breakpoint;
import static org.eclipse.che.plugin.debugger.ide.DebuggerExtension.BREAKPOINT;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import org.eclipse.che.api.debug.shared.model.Breakpoint;
import org.eclipse.che.ide.api.action.Action;
import org.eclipse.che.ide.api.action.ActionManager;
import org.eclipse.che.ide.api.action.Presentation;
import org.eclipse.che.ide.api.keybinding.KeyBindingAgent;
import org.eclipse.che.ide.api.parts.PerspectiveManager;
import org.eclipse.che.ide.menu.ContextMenu;
import org.eclipse.che.plugin.debugger.ide.DebuggerExtension;
/** @author Anatolii Bazko */
public class BreakpointContextMenu extends ContextMenu {
private final Breakpoint breakpoint;
@Inject
public BreakpointContextMenu(
@Assisted Breakpoint breakpoint,
ActionManager actionManager,
KeyBindingAgent keyBindingAgent,
Provider<PerspectiveManager> managerProvider) {
super(actionManager, keyBindingAgent, managerProvider);
this.breakpoint = breakpoint;
}
@Override
protected String getGroupMenu() {
return DebuggerExtension.BREAKPOINT_CONTEXT_MENU;
}
@Override
public void onActionSelected(Action action) {
Presentation presentation = action.getTemplatePresentation();
presentation.putClientProperty(BREAKPOINT, breakpoint);
super.onActionSelected(action);
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.debugger.ide.debug.breakpoint;
import org.eclipse.che.api.debug.shared.model.Breakpoint;
/**
* Breakpoint context menu factory.
*
* @author Anatolii Bazko
*/
public interface BreakpointContextMenuFactory {
/**
* Creates new context menu for a given breakpoint.
*
* @param breakpoint the breakpoint
* @return new context menu
*/
BreakpointContextMenu newContextMenu(Breakpoint breakpoint);
}

View File

@ -25,6 +25,9 @@ import org.eclipse.che.plugin.debugger.ide.configuration.EditDebugConfigurations
import org.eclipse.che.plugin.debugger.ide.debug.DebuggerToolbar;
import org.eclipse.che.plugin.debugger.ide.debug.DebuggerView;
import org.eclipse.che.plugin.debugger.ide.debug.DebuggerViewImpl;
import org.eclipse.che.plugin.debugger.ide.debug.breakpoint.BreakpointConfigurationView;
import org.eclipse.che.plugin.debugger.ide.debug.breakpoint.BreakpointConfigurationViewImpl;
import org.eclipse.che.plugin.debugger.ide.debug.breakpoint.BreakpointContextMenuFactory;
import org.eclipse.che.plugin.debugger.ide.debug.changevalue.ChangeValueView;
import org.eclipse.che.plugin.debugger.ide.debug.changevalue.ChangeValueViewImpl;
import org.eclipse.che.plugin.debugger.ide.debug.expression.EvaluateExpressionView;
@ -44,6 +47,7 @@ public class DebuggerGinModule extends AbstractGinModule {
bind(DebuggerView.class).to(DebuggerViewImpl.class).in(Singleton.class);
bind(EvaluateExpressionView.class).to(EvaluateExpressionViewImpl.class).in(Singleton.class);
bind(ChangeValueView.class).to(ChangeValueViewImpl.class).in(Singleton.class);
bind(BreakpointConfigurationView.class).to(BreakpointConfigurationViewImpl.class);
bind(EditDebugConfigurationsView.class)
.to(EditDebugConfigurationsViewImpl.class)
.in(Singleton.class);
@ -60,5 +64,7 @@ public class DebuggerGinModule extends AbstractGinModule {
.annotatedWith(DebuggerToolbar.class)
.to(ToolbarPresenter.class)
.in(Singleton.class);
install(new GinFactoryModuleBuilder().build(BreakpointContextMenuFactory.class));
}
}

View File

@ -30,6 +30,7 @@ deleteAllBreakpoints = Remove All Breakpoints
changeVariableValue = Change Value
evaluateExpression = Evaluate Expression
showHideDebuggerPanel=Show/Hide Debugger Panel
breakpointConfiguration=Configuration
##### Descriptions #####
editDebugConfigurationsActionDescription = Edit debug configurations
@ -44,6 +45,7 @@ deleteAllBreakpointsDescription = Remove All Breakpoints
changeVariableValueDescription = Change Value
evaluateExpressionDescription = Evaluate Expression
showHideDebuggerPanelDescription=Show/Hide Debugger Panel
breakpointConfigurationDescription=Breakpoint Configuration
############### Messages ################
debugger.connecting.title = Connecting to {0}
@ -60,6 +62,7 @@ view.changeValue.title = Change variable value
view.changeValue.expressionField.title = Enter a new value for <b>{0}</b>:
view.changeValue.changeButton.title = Change
view.changeValue.cancelButton.title = Cancel
view.breakpoint.configuration.title = Configuration
############### EvaluateExpressionView ################
view.evaluateExpression.title = Evaluate expression
@ -69,6 +72,11 @@ view.evaluateExpression.evaluateButton.title = Evaluate
view.evaluateExpression.closeButton.title = Close
evaluateExpressionFailed = Error: Failed to evaluate an expression.\r\nReason: {0}
############### BreakpointConfigurationView #################
view.breakpointConfiguration.condition = Condition:
view.breakpointConfiguration.hitCount = Hit Count:
view.breakpointConfiguration.applyButton = Apply
# EditConfigurations
view.editConfigurations.placeholder=Filter
view.editConfigurations.title=Debug Configurations

View File

@ -43,6 +43,7 @@ import org.eclipse.che.ide.ui.toolbar.ToolbarPresenter;
import org.eclipse.che.plugin.debugger.ide.BaseTest;
import org.eclipse.che.plugin.debugger.ide.DebuggerLocalizationConstant;
import org.eclipse.che.plugin.debugger.ide.DebuggerResources;
import org.eclipse.che.plugin.debugger.ide.debug.breakpoint.BreakpointContextMenuFactory;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -74,6 +75,7 @@ public class DebuggerPresenterTest extends BaseTest {
@Mock private DebuggerManager debuggerManager;
@Mock private WorkspaceAgent workspaceAgent;
@Mock private DebuggerResourceHandlerFactory debuggerResourceHandlerFactory;
@Mock private BreakpointContextMenuFactory breakpointContextMenuFactory;
@Mock private Debugger debugger;
@Mock private MutableVariable selectedVariable;
@ -108,7 +110,8 @@ public class DebuggerPresenterTest extends BaseTest {
debuggerToolbar,
debuggerManager,
workspaceAgent,
debuggerResourceHandlerFactory));
debuggerResourceHandlerFactory,
breakpointContextMenuFactory));
Mockito.reset(view);
when(view.getSelectedThreadId()).thenReturn(THREAD_ID);

View File

@ -421,8 +421,9 @@ public class DebuggerTest extends BaseTest {
when(breakpointDto.getLocation().getLineNumber()).thenReturn(LINE_NUMBER);
when(breakpointDto.withLocation(locationDto)).thenReturn(breakpointDto);
when(breakpointDto.withEnabled(true)).thenReturn(breakpointDto);
when(breakpointDto.withCondition(any())).thenReturn(breakpointDto);
debugger.addBreakpoint(virtualFile, breakpointDto);
debugger.addBreakpoint(breakpointDto);
verify(service).addBreakpoint(SESSION_ID, breakpointDto);
verify(promiseVoid).then(operationVoidCaptor.capture());
@ -440,7 +441,7 @@ public class DebuggerTest extends BaseTest {
doReturn(promiseVoid).when(service).deleteBreakpoint(SESSION_ID, locationDto);
doReturn(promiseVoid).when(promiseVoid).then((Operation<Void>) any());
debugger.deleteBreakpoint(file, breakpointDto);
debugger.deleteBreakpoint(breakpointDto);
verify(promiseVoid).then(operationVoidCaptor.capture());
operationVoidCaptor.getValue().apply(null);
@ -455,7 +456,7 @@ public class DebuggerTest extends BaseTest {
@Test
public void testDeleteBreakpointWithoutConnection() throws Exception {
debugger.setDebugSession(null);
debugger.deleteBreakpoint(file, breakpointDto);
debugger.deleteBreakpoint(breakpointDto);
verify(service, never()).deleteBreakpoint(any(), any());
}

View File

@ -26,7 +26,6 @@ import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.debug.BreakpointManager;
import org.eclipse.che.ide.api.debug.DebuggerServiceClient;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.resources.VirtualFile;
import org.eclipse.che.ide.debug.DebuggerDescriptor;
import org.eclipse.che.ide.debug.DebuggerManager;
import org.eclipse.che.ide.dto.DtoFactory;
@ -79,12 +78,12 @@ public class GdbDebugger extends AbstractDebugger {
}
@Override
public void addBreakpoint(final VirtualFile file, final Breakpoint breakpoint) {
public void addBreakpoint(final Breakpoint breakpoint) {
if (isConnected() && !isSuspended()) {
notificationManager.notify(locale.messageSuspendToActivateBreakpoints(), FAIL, FLOAT_MODE);
}
super.addBreakpoint(file, breakpoint);
super.addBreakpoint(breakpoint);
}
@Override

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.plugin.jdb.server;
import static org.eclipse.che.plugin.jdb.server.util.JavaDebuggerUtils.ensureSuspendAtDesiredLocation;
import static org.eclipse.che.plugin.jdb.server.util.JavaDebuggerUtils.startJavaDebugger;
import static org.eclipse.che.plugin.jdb.server.util.JavaDebuggerUtils.terminateVirtualMachineQuietly;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import org.eclipse.che.api.debug.shared.model.Breakpoint;
import org.eclipse.che.api.debug.shared.model.Location;
import org.eclipse.che.api.debug.shared.model.event.BreakpointActivatedEvent;
import org.eclipse.che.api.debug.shared.model.event.DebuggerEvent;
import org.eclipse.che.api.debug.shared.model.event.DisconnectEvent;
import org.eclipse.che.api.debug.shared.model.event.SuspendEvent;
import org.eclipse.che.api.debug.shared.model.impl.BreakpointImpl;
import org.eclipse.che.api.debug.shared.model.impl.LocationImpl;
import org.eclipse.che.api.debug.shared.model.impl.action.ResumeActionImpl;
import org.eclipse.che.plugin.jdb.server.util.ProjectApiUtils;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/** @author Anatolii Bazko */
public class BreakpointConditionTest {
private JavaDebugger debugger;
private BlockingQueue<DebuggerEvent> events;
@BeforeClass
public void setUp() throws Exception {
ProjectApiUtils.ensure();
Location location =
new LocationImpl(
"/test/src/org/eclipse/BreakpointsByConditionTest.java",
17,
false,
-1,
"/test",
null,
-1);
events = new ArrayBlockingQueue<>(10);
debugger = startJavaDebugger(new BreakpointImpl(location), events);
ensureSuspendAtDesiredLocation(location, events);
}
@AfterClass
public void tearDown() throws Exception {
if (debugger != null) {
terminateVirtualMachineQuietly(debugger);
}
}
@Test
public void shouldStopByCondition() throws Exception {
Breakpoint breakpoint =
new BreakpointImpl(
new LocationImpl(
"/test/src/org/eclipse/BreakpointsByConditionTest.java",
19,
false,
-1,
"/test",
null,
-1),
true,
"i==5");
debugger.addBreakpoint(breakpoint);
DebuggerEvent debuggerEvent = events.take();
assertTrue(debuggerEvent instanceof BreakpointActivatedEvent);
debugger.resume(new ResumeActionImpl());
debuggerEvent = events.take();
assertTrue(debuggerEvent instanceof SuspendEvent);
assertEquals("5", debugger.evaluate("i"));
assertEquals("4", debugger.evaluate("k"));
debugger.resume(new ResumeActionImpl());
debuggerEvent = events.take();
assertTrue(debuggerEvent instanceof DisconnectEvent);
}
}

View File

@ -16,6 +16,7 @@
<test name="all">
<classes>
<class name="org.eclipse.che.plugin.jdb.server.BreakpointsTest"/>
<class name="org.eclipse.che.plugin.jdb.server.BreakpointConditionTest"/>
<class name="org.eclipse.che.plugin.jdb.server.ThreadDumpTest1"/>
<class name="org.eclipse.che.plugin.jdb.server.ThreadDumpTest2"/>
<class name="org.eclipse.che.plugin.jdb.server.StackFrameDumpTest1"/>

View File

@ -37,6 +37,10 @@
<source>${project.build.testOutputDirectory}/workspace/test/src/org/eclipse/BreakpointsTest.java</source>
<outputDirectory>./org/eclipse</outputDirectory>
</file>
<file>
<source>${project.build.testOutputDirectory}/workspace/test/src/org/eclipse/BreakpointsByConditionTest.java</source>
<outputDirectory>./org/eclipse</outputDirectory>
</file>
<file>
<source>${project.build.testOutputDirectory}/workspace/test/src/com/HelloWorld.java</source>
<outputDirectory>./com</outputDirectory>

View File

@ -18,10 +18,12 @@ javac -g org/eclipse/GetValueTest1.java
javac -g org/eclipse/EvaluateExpressionTest1.java
javac -g com/HelloWorld.java
javac -g org/eclipse/BreakpointsTest.java
javac -g org/eclipse/BreakpointsByConditionTest.java
DEBUG_OPT="-Xdebug -Xrunjdwp:transport=dt_socket,address=8001,server=y,suspend=y"
java ${DEBUG_OPT} org.eclipse.BreakpointsTest
java ${DEBUG_OPT} org.eclipse.BreakpointsByConditionTest
java ${DEBUG_OPT} org.eclipse.ThreadDumpTest1
java ${DEBUG_OPT} org.eclipse.ThreadDumpTest2
java ${DEBUG_OPT} org.eclipse.StackFrameDumpTest1

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse;
/** @author Anatolii Bazko */
public class BreakpointsByConditionTest {
public static void main(String[] args) {
int k = 0;
for (int i = 0; i < 10; i++) {
k = i;
}
}
}

View File

@ -316,4 +316,8 @@ public class SeleniumWebDriver
new WebDriverWait(this, timeout)
.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("ide-application-iframe")));
}
public WebDriverWait wait(int timeOutInSeconds) {
return new WebDriverWait(this, timeOutInSeconds);
}
}

View File

@ -25,7 +25,6 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.textToBePresentI
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOf;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfAllElementsLocatedBy;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;
import static org.testng.Assert.fail;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@ -194,6 +193,8 @@ public class CodenvyEditor {
"//div[@class='breakpoint inactive' and text()='%d']";
public static final String DEBUGGER_BREAK_POINT_ACTIVE =
"//div[@class='breakpoint active' and text()='%d']";
public static final String DEBUGGER_BREAKPOINT_CONDITION =
"//div[@class='breakpoint %s condition' and text()='%d']";
public static final String JAVA_DOC_POPUP = "//div[@class='gwt-PopupPanel']//iframe";
public static final String AUTOCOMPLETE_PROPOSAL_JAVA_DOC_POPUP =
"//div//iframe[contains(@src, 'api/java/code-assist/compute/info?')]";
@ -1190,18 +1191,14 @@ public class CodenvyEditor {
By.xpath(String.format(Locators.DEBUGGER_BREAK_POINT_INACTIVE, position))));
}
public void waitBreakpointRemoved(int position) {
try {
waitInactiveBreakpoint(position);
fail("Breakpoint should be removed at " + position);
} catch (Exception e) {
}
try {
waitActiveBreakpoint(position);
fail("Breakpoint should be removed at " + position);
} catch (Exception e) {
}
public void waitConditionalBreakpoint(int lineNumber, boolean active) {
redrawDriverWait.until(
visibilityOfElementLocated(
By.xpath(
String.format(
Locators.DEBUGGER_BREAKPOINT_CONDITION,
active ? "active" : "inactive",
lineNumber))));
}
/** wait while editor will be empty */

View File

@ -10,15 +10,20 @@
*/
package org.eclipse.che.selenium.pageobject.debug;
import static java.lang.String.format;
import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.LOAD_PAGE_TIMEOUT_SEC;
import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.MINIMUM_SEC;
import static org.eclipse.che.selenium.core.constant.TestTimeoutsConstants.REDRAW_UI_ELEMENTS_TIMEOUT_SEC;
import static org.openqa.selenium.By.id;
import static org.openqa.selenium.By.xpath;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;
import com.google.common.base.Function;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.List;
import org.eclipse.che.selenium.core.SeleniumWebDriver;
import org.eclipse.che.selenium.core.action.ActionsFactory;
import org.eclipse.che.selenium.pageobject.CodenvyEditor;
import org.eclipse.che.selenium.pageobject.Loader;
import org.eclipse.che.selenium.pageobject.intelligent.CommandsExplorer;
@ -41,26 +46,28 @@ public class DebugPanel {
private static final Logger LOG = LoggerFactory.getLogger(DebugPanel.class);
@Inject private SeleniumWebDriver seleniumWebDriver;
@Inject private Loader loader;
@Inject private CodenvyEditor editor;
@Inject private CommandsExplorer commandsExplorer;
private SeleniumWebDriver seleniumWebDriver;
private Loader loader;
private CodenvyEditor editor;
private CommandsExplorer commandsExplorer;
private ActionsFactory actionsFactory;
@Inject
public DebugPanel(
SeleniumWebDriver seleniumWebDriver,
Loader loader,
CodenvyEditor editor,
CommandsExplorer commandsExplorer) {
CommandsExplorer commandsExplorer,
ActionsFactory actionsFactory) {
this.seleniumWebDriver = seleniumWebDriver;
this.loader = loader;
this.editor = editor;
this.commandsExplorer = commandsExplorer;
this.actionsFactory = actionsFactory;
PageFactory.initElements(seleniumWebDriver, this);
}
private interface Locators {
String DEBUGGER_BREAKPOINTS_PANEL_ID = "gwt-debug-debugger-breakpointsPanel";
String DEBUGGER_PANEL_TAB = "gwt-debug-partButton-Debug";
String FRAMES_LIST_ID = "gwt-debug-debugger-frames-list";
String THREADS_LIST_ID = "gwt-debug-debugger-threads-list";
@ -87,8 +94,21 @@ public class DebugPanel {
String EVALUATE_EXPRESSIONS = "gwt-debug-ActionButton/evaluateExpression-true";
}
@FindBy(id = Locators.DEBUGGER_BREAKPOINTS_PANEL_ID)
WebElement debuggerBreakPointPanel;
private interface BreakpointsPanel {
String ID = "gwt-debug-debugger-breakpointsPanel";
String BREAKPOINT_ITEM = "//div[@id='gwt-debug-debugger-breakpointsPanel']//td[text()='%s']";
String CONTEXT_MENU = "gwt-debug-contextMenu/breakpointSettings";
}
private interface BreakpointConfigurationWindow {
String BREAKPOINT_CONDITION_TEXT =
"//div[@id='gwt-debug-breakpoint-configuration-window']//textarea[@id='gwt-debug-breakpoint-condition-text']";
String APPLY_BTN =
"//div[@id='gwt-debug-breakpoint-configuration-window']//button[@id='gwt-debug-apply-btn']";
}
@FindBy(id = BreakpointsPanel.ID)
WebElement breakpointPanel;
@FindBy(id = Locators.DEBUGGER_PANEL_TAB)
WebElement debuggerTab;
@ -126,16 +146,15 @@ public class DebugPanel {
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(
(WebDriver webDriver) -> {
return debuggerBreakPointPanel.getText().contains(content);
return breakpointPanel.getText().contains(content);
});
}
/** Wait disappearance any breakpoints from debugger breakpoints panel */
public void waitBreakPointsPanelIsEmpty() {
new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC)
.until(
(WebDriver webDriver) -> {
return debuggerBreakPointPanel.getText().isEmpty();
return breakpointPanel.getText().isEmpty();
});
}
@ -163,10 +182,10 @@ public class DebugPanel {
public void selectVarInVariablePanel(String variable) {
new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC)
.until(
ExpectedConditions.visibilityOfElementLocated(
By.xpath(String.format(Locators.VARIABLE_PANEL_SELECT_VAL, variable))));
visibilityOfElementLocated(
xpath(format(Locators.VARIABLE_PANEL_SELECT_VAL, variable))));
seleniumWebDriver
.findElement(By.xpath(String.format(Locators.VARIABLE_PANEL_SELECT_VAL, variable)))
.findElement(xpath(format(Locators.VARIABLE_PANEL_SELECT_VAL, variable)))
.click();
}
@ -178,8 +197,8 @@ public class DebugPanel {
public void clickOnButton(String buttonIdLocator) {
loader.waitOnClosed();
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(ExpectedConditions.visibilityOfElementLocated(By.id(buttonIdLocator)));
seleniumWebDriver.findElement(By.id(buttonIdLocator)).click();
.until(visibilityOfElementLocated(id(buttonIdLocator)));
seleniumWebDriver.findElement(id(buttonIdLocator)).click();
loader.waitOnClosed();
}
@ -194,7 +213,7 @@ public class DebugPanel {
new WebDriverWait(seleniumWebDriver, 20)
.until(
ExpectedConditions.invisibilityOfElementLocated(
By.xpath(LocatorsChangeVariable.TEXTAREA)));
xpath(LocatorsChangeVariable.TEXTAREA)));
}
/**
@ -229,10 +248,10 @@ public class DebugPanel {
String exprFieldLocator =
"//div[text()='Enter an expression:']/parent::div/following-sibling::div/input";
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(exprFieldLocator)))
.until(visibilityOfElementLocated(xpath(exprFieldLocator)))
.clear();
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(exprFieldLocator)))
.until(visibilityOfElementLocated(xpath(exprFieldLocator)))
.sendKeys(expression);
}
@ -248,7 +267,7 @@ public class DebugPanel {
(ExpectedCondition<Boolean>)
webDriver -> {
return seleniumWebDriver
.findElement(By.xpath(locator))
.findElement(xpath(locator))
.getAttribute("value")
.equals(expVal);
});
@ -258,7 +277,7 @@ public class DebugPanel {
public void clickEvaluateBtn() {
String locator = "//button[text()='Evaluate']";
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator)))
.until(visibilityOfElementLocated(xpath(locator)))
.click();
}
@ -266,10 +285,10 @@ public class DebugPanel {
public void clickCloseEvaluateBtn() {
String locator = "//button[text()='Evaluate']/preceding-sibling::button";
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(locator)))
.until(visibilityOfElementLocated(xpath(locator)))
.click();
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath(locator)));
.until(ExpectedConditions.invisibilityOfElementLocated(xpath(locator)));
}
/**
@ -281,7 +300,7 @@ public class DebugPanel {
try {
return seleniumWebDriver
.findElement(By.id(DebuggerButtonsPanel.REMOVE_ALL_BREAKPOINTS))
.findElement(id(DebuggerButtonsPanel.REMOVE_ALL_BREAKPOINTS))
.isDisplayed();
} catch (Exception ex) {
return false;
@ -301,7 +320,7 @@ public class DebugPanel {
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(
ExpectedConditions.presenceOfAllElementsLocatedBy(
By.xpath(locatorWithHiglightedText)));
xpath(locatorWithHiglightedText)));
for (WebElement hilightedElement : hilightedElements) {
highLightedText.append(hilightedElement.getText());
}
@ -322,7 +341,7 @@ public class DebugPanel {
editor.waitActiveEditor();
List<WebElement> editorLines =
seleniumWebDriver.findElements(
By.xpath(
xpath(
"//div[@id='gwt-debug-editorPartStack-contentPanel']//div[@active]//div[@class='textviewContent' and @contenteditable='true']/div"));
new WebDriverWait(seleniumWebDriver, LOAD_PAGE_TIMEOUT_SEC)
.until(
@ -415,9 +434,7 @@ public class DebugPanel {
waitFramesListPanelReady();
new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC)
.until(
ExpectedConditions.visibilityOfElementLocated(
By.xpath("//td[text()='" + getFrames()[frameIndex] + "']")))
.until(visibilityOfElementLocated(xpath("//td[text()='" + getFrames()[frameIndex] + "']")))
.click();
}
@ -444,10 +461,39 @@ public class DebugPanel {
threads.click();
new WebDriverWait(seleniumWebDriver, REDRAW_UI_ELEMENTS_TIMEOUT_SEC)
.until(
ExpectedConditions.visibilityOfElementLocated(
By.xpath("//*[contains(text(),'\"" + threadName + "\"@')]")))
.until(visibilityOfElementLocated(xpath("//*[contains(text(),'\"" + threadName + "\"@')]")))
.click();
threads.click();
}
public void makeBreakpointConditional(String fileName, int lineNumber, String condition) {
String breakpointItem = format(BreakpointsPanel.BREAKPOINT_ITEM, fileName + ":" + lineNumber);
seleniumWebDriver
.wait(REDRAW_UI_ELEMENTS_TIMEOUT_SEC)
.until(visibilityOfElementLocated(xpath(breakpointItem)));
actionsFactory
.createAction(seleniumWebDriver)
.contextClick(seleniumWebDriver.findElement(xpath(breakpointItem)))
.build()
.perform();
seleniumWebDriver
.wait(REDRAW_UI_ELEMENTS_TIMEOUT_SEC)
.until(visibilityOfElementLocated(id(BreakpointsPanel.CONTEXT_MENU)))
.click();
seleniumWebDriver
.wait(REDRAW_UI_ELEMENTS_TIMEOUT_SEC)
.until(
visibilityOfElementLocated(
xpath(BreakpointConfigurationWindow.BREAKPOINT_CONDITION_TEXT)))
.sendKeys(condition);
seleniumWebDriver
.wait(REDRAW_UI_ELEMENTS_TIMEOUT_SEC)
.until(visibilityOfElementLocated(xpath(BreakpointConfigurationWindow.APPLY_BTN)))
.click();
}
}

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.selenium.debugger;
import static org.eclipse.che.selenium.core.constant.TestCommandsConstants.CUSTOM;
import static org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Run.EDIT_DEBUG_CONFIGURATION;
import static org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants.Run.RUN_MENU;
import static org.eclipse.che.selenium.core.project.ProjectTemplates.PLAIN_JAVA;
import static org.eclipse.che.selenium.pageobject.debug.DebugPanel.DebuggerButtonsPanel.RESUME_BTN_ID;
import com.google.inject.Inject;
import java.nio.file.Paths;
import org.eclipse.che.commons.lang.NameGenerator;
import org.eclipse.che.selenium.core.client.TestCommandServiceClient;
import org.eclipse.che.selenium.core.client.TestProjectServiceClient;
import org.eclipse.che.selenium.core.constant.TestBuildConstants;
import org.eclipse.che.selenium.core.constant.TestMenuCommandsConstants;
import org.eclipse.che.selenium.core.workspace.TestWorkspace;
import org.eclipse.che.selenium.pageobject.CodenvyEditor;
import org.eclipse.che.selenium.pageobject.Consoles;
import org.eclipse.che.selenium.pageobject.Ide;
import org.eclipse.che.selenium.pageobject.Menu;
import org.eclipse.che.selenium.pageobject.NotificationsPopupPanel;
import org.eclipse.che.selenium.pageobject.ProjectExplorer;
import org.eclipse.che.selenium.pageobject.debug.DebugPanel;
import org.eclipse.che.selenium.pageobject.debug.JavaDebugConfig;
import org.eclipse.che.selenium.pageobject.intelligent.CommandsPalette;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/** @author Musienko Maxim */
public class ConditionalBreakpointsTest {
private static final String PROJECT = NameGenerator.generate("project", 2);
@Inject private TestWorkspace ws;
@Inject private Ide ide;
@Inject private ProjectExplorer projectExplorer;
@Inject private CodenvyEditor editor;
@Inject private DebugPanel debugPanel;
@Inject private TestProjectServiceClient testProjectServiceClient;
@Inject private TestCommandServiceClient testCommandServiceClient;
@Inject private CommandsPalette commandsPalette;
@Inject private Consoles consoles;
@Inject private Menu menu;
@Inject private NotificationsPopupPanel notifications;
@Inject private JavaDebugConfig debugConfig;
@BeforeClass
public void setUp() throws Exception {
testProjectServiceClient.importProject(
ws.getId(),
Paths.get(getClass().getResource("/projects/plugins/DebuggerPlugin/hello-world").toURI()),
PROJECT,
PLAIN_JAVA);
testCommandServiceClient.createCommand(
"cd ${current.project.path}/src/ && javac -g HelloWorld.java &&"
+ " java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y HelloWorld",
"debug",
CUSTOM,
ws.getId());
ide.open(ws);
projectExplorer.waitItem(PROJECT);
projectExplorer.quickExpandWithJavaScript();
debugPanel.openDebugPanel();
projectExplorer.openItemByPath(PROJECT + "/src/HelloWorld.java");
}
@Test
public void shouldAddConditionalBreakpoint() throws Exception {
editor.setBreakpoint(14);
editor.setBreakpoint(15);
editor.waitInactiveBreakpoint(15);
debugPanel.makeBreakpointConditional("HelloWorld.java", 15, "i == 3");
editor.waitConditionalBreakpoint(15, false);
projectExplorer.selectItem(PROJECT);
startDebug();
editor.waitConditionalBreakpoint(15, true);
debugPanel.clickOnButton(RESUME_BTN_ID);
debugPanel.waitTextInVariablesPanel("i=3");
}
private void startDebug() {
menu.runCommand(RUN_MENU, EDIT_DEBUG_CONFIGURATION);
debugConfig.createConfig(PROJECT);
commandsPalette.openCommandPalette();
commandsPalette.startCommandByDoubleClick("debug");
consoles.waitExpectedTextIntoConsole(TestBuildConstants.LISTENING_AT_ADDRESS_8000);
menu.runCommandByXpath(
TestMenuCommandsConstants.Run.RUN_MENU,
TestMenuCommandsConstants.Run.DEBUG,
debugConfig.getXpathToІRunDebugCommand(PROJECT));
notifications.waitExpectedMessageOnProgressPanelAndClosed("Remote debugger connected");
}
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2012-2017 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
public class HelloWorld {
public static void main(String[] arg) {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}

View File

@ -85,6 +85,7 @@
<class name="org.eclipse.che.selenium.debugger.StepIntoStepOverStepReturnWithChangeVariableTest"/>
<class name="org.eclipse.che.selenium.debugger.ThreadDumpTest"/>
<class name="org.eclipse.che.selenium.debugger.BreakpointReorderingTest"/>
<class name="org.eclipse.che.selenium.debugger.ConditionalBreakpointsTest"/>
<class name="org.eclipse.che.selenium.editor.autocomplete.AutocompleteFeaturesInEditorTest"/>
<class name="org.eclipse.che.selenium.editor.autocomplete.AutocompleteJSFilesTest"/>
<class name="org.eclipse.che.selenium.editor.autocomplete.AutocompleteProposalJavaDocTest">

View File

@ -20,4 +20,6 @@ public interface Breakpoint {
/** The condition. */
String getCondition();
void setCondition(String condition);
}

View File

@ -16,8 +16,8 @@ import org.eclipse.che.api.debug.shared.model.Location;
/** @author Anatoliy Bazko */
public class BreakpointImpl implements Breakpoint {
private final Location location;
private final boolean enabled;
private final String condition;
private boolean enabled;
private String condition;
public BreakpointImpl(Location location, boolean enabled, String condition) {
this.location = location;
@ -44,6 +44,11 @@ public class BreakpointImpl implements Breakpoint {
return condition;
}
@Override
public void setCondition(String condition) {
this.condition = condition;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;