/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.api.debugger.server; import com.google.inject.Inject; import org.eclipse.che.api.debug.shared.dto.BreakpointDto; import org.eclipse.che.api.debug.shared.dto.DebugSessionDto; import org.eclipse.che.api.debug.shared.dto.SimpleValueDto; import org.eclipse.che.api.debug.shared.dto.StackFrameDumpDto; import org.eclipse.che.api.debug.shared.dto.VariableDto; import org.eclipse.che.api.debug.shared.dto.action.ActionDto; import org.eclipse.che.api.debug.shared.model.Location; import org.eclipse.che.api.debug.shared.model.VariablePath; import org.eclipse.che.api.debug.shared.model.action.ResumeAction; import org.eclipse.che.api.debug.shared.model.action.StartAction; import org.eclipse.che.api.debug.shared.model.action.StepIntoAction; import org.eclipse.che.api.debug.shared.model.action.StepOutAction; import org.eclipse.che.api.debug.shared.model.action.StepOverAction; import org.eclipse.che.api.debug.shared.model.impl.LocationImpl; import org.eclipse.che.api.debug.shared.model.impl.VariablePathImpl; import org.eclipse.che.api.debugger.server.exceptions.DebuggerException; import org.eclipse.che.api.debugger.server.exceptions.DebuggerNotFoundException; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriInfo; import java.util.ArrayList; import java.util.List; import java.util.Map; import static org.eclipse.che.api.debugger.server.DtoConverter.asBreakpointsDto; import static org.eclipse.che.api.debugger.server.DtoConverter.asDto; import static org.eclipse.che.dto.server.DtoFactory.newDto; /** * Debugger REST API. * * @author Anatoliy Bazko */ @Path("debugger") public class DebuggerService { private final DebuggerManager debuggerManager; @Inject public DebuggerService(DebuggerManager debuggerManager) { this.debuggerManager = debuggerManager; } @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public DebugSessionDto connect(final @QueryParam("type") String debuggerType, final Map<String, String> properties) throws DebuggerException { String sessionId = debuggerManager.create(debuggerType, properties); return getDebugSession(sessionId); } @DELETE @Path("{id}") public void disconnect(@PathParam("id") String sessionId) throws DebuggerException { Debugger debugger; try { debugger = debuggerManager.getDebugger(sessionId); } catch (DebuggerNotFoundException e) { // probably already disconnected return; } debugger.disconnect(); } @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public DebugSessionDto getDebugSession(@PathParam("id") String sessionId) throws DebuggerException { Debugger debugger = debuggerManager.getDebugger(sessionId); DebugSessionDto debugSessionDto = newDto(DebugSessionDto.class); debugSessionDto.setDebuggerInfo(asDto(debugger.getInfo())); debugSessionDto.setId(sessionId); debugSessionDto.setType(debuggerManager.getDebuggerType(sessionId)); debugSessionDto.setBreakpoints(asBreakpointsDto(debugger.getAllBreakpoints())); return debugSessionDto; } @POST @Path("{id}") public void performAction(@PathParam("id") String sessionId, ActionDto action) throws DebuggerException { Debugger debugger = debuggerManager.getDebugger(sessionId); switch (action.getType()) { case START: debugger.start((StartAction)action); break; case RESUME: debugger.resume((ResumeAction)action); break; case SUSPEND: debugger.suspend(); break; case STEP_INTO: debugger.stepInto((StepIntoAction)action); break; case STEP_OUT: debugger.stepOut((StepOutAction)action); break; case STEP_OVER: debugger.stepOver((StepOverAction)action); break; default: throw new DebuggerException("Unknown debugger action type " + action.getType()); } } @POST @Path("{id}/breakpoint") @Consumes(MediaType.APPLICATION_JSON) public void addBreakpoint(@PathParam("id") String sessionId, BreakpointDto breakpoint) throws DebuggerException { debuggerManager.getDebugger(sessionId).addBreakpoint(breakpoint); } @GET @Path("{id}/breakpoint") @Produces(MediaType.APPLICATION_JSON) public List<BreakpointDto> getBreakpoints(@PathParam("id") String sessionId) throws DebuggerException { return asBreakpointsDto(debuggerManager.getDebugger(sessionId).getAllBreakpoints()); } @DELETE @Path("{id}/breakpoint") public void deleteBreakpoint(@PathParam("id") String sessionId, @QueryParam("target") String target, @QueryParam("line") @DefaultValue("0") int lineNumber) throws DebuggerException { if (target == null) { debuggerManager.getDebugger(sessionId).deleteAllBreakpoints(); } else { Location location = new LocationImpl(target, lineNumber); debuggerManager.getDebugger(sessionId).deleteBreakpoint(location); } } @GET @Path("{id}/dump") @Produces(MediaType.APPLICATION_JSON) public StackFrameDumpDto getStackFrameDump(@PathParam("id") String sessionId) throws DebuggerException { return asDto(debuggerManager.getDebugger(sessionId).dumpStackFrame()); } @GET @Path("{id}/value") @Produces(MediaType.APPLICATION_JSON) public SimpleValueDto getValue(@PathParam("id") String sessionId, @Context UriInfo uriInfo) throws DebuggerException { List<String> path = new ArrayList<>(); MultivaluedMap<String, String> parameters = uriInfo.getQueryParameters(); int i = 0; String item; while ((item = parameters.getFirst("path" + (i++))) != null) { path.add(item); } VariablePath variablePath = new VariablePathImpl(path); return asDto(debuggerManager.getDebugger(sessionId).getValue(variablePath)); } @PUT @Path("{id}/value") @Consumes(MediaType.APPLICATION_JSON) public void setValue(@PathParam("id") String sessionId, VariableDto variable) throws DebuggerException { debuggerManager.getDebugger(sessionId).setValue(variable); } @GET @Path("{id}/evaluation") @Produces(MediaType.TEXT_PLAIN) public String expression(@PathParam("id") String sessionId, @QueryParam("expression") String expression) throws DebuggerException { return debuggerManager.getDebugger(sessionId).evaluate(expression); } }