Attach, Continue, Set Breakpoints.
1.1 --- a/dew4nb/nbproject/project.xml Tue Jan 28 10:20:31 2014 +0100
1.2 +++ b/dew4nb/nbproject/project.xml Tue Jan 28 13:57:53 2014 +0100
1.3 @@ -15,6 +15,24 @@
1.4 </run-dependency>
1.5 </dependency>
1.6 <dependency>
1.7 + <code-name-base>org.netbeans.api.debugger</code-name-base>
1.8 + <build-prerequisite/>
1.9 + <compile-dependency/>
1.10 + <run-dependency>
1.11 + <release-version>1</release-version>
1.12 + <specification-version>1.45</specification-version>
1.13 + </run-dependency>
1.14 + </dependency>
1.15 + <dependency>
1.16 + <code-name-base>org.netbeans.api.debugger.jpda</code-name-base>
1.17 + <build-prerequisite/>
1.18 + <compile-dependency/>
1.19 + <run-dependency>
1.20 + <release-version>2</release-version>
1.21 + <specification-version>2.48</specification-version>
1.22 + </run-dependency>
1.23 + </dependency>
1.24 + <dependency>
1.25 <code-name-base>org.netbeans.api.java.classpath</code-name-base>
1.26 <build-prerequisite/>
1.27 <compile-dependency/>
1.28 @@ -32,6 +50,15 @@
1.29 </run-dependency>
1.30 </dependency>
1.31 <dependency>
1.32 + <code-name-base>org.netbeans.modules.debugger.jpda</code-name-base>
1.33 + <build-prerequisite/>
1.34 + <compile-dependency/>
1.35 + <run-dependency>
1.36 + <release-version>2</release-version>
1.37 + <specification-version>1.63</specification-version>
1.38 + </run-dependency>
1.39 + </dependency>
1.40 + <dependency>
1.41 <code-name-base>org.netbeans.modules.editor.completion</code-name-base>
1.42 <build-prerequisite/>
1.43 <compile-dependency/>
2.1 --- a/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/JavacMessageType.java Tue Jan 28 10:20:31 2014 +0100
2.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/JavacMessageType.java Tue Jan 28 13:57:53 2014 +0100
2.3 @@ -56,4 +56,5 @@
2.4 //debugger
2.5 attach,
2.6 breakpoints,
2.7 + cont
2.8 }
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/debugger/ActiveSessions.java Tue Jan 28 13:57:53 2014 +0100
3.3 @@ -0,0 +1,133 @@
3.4 +/*
3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3.6 + *
3.7 + * Copyright 2014 Oracle and/or its affiliates. All rights reserved.
3.8 + *
3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
3.10 + * Other names may be trademarks of their respective owners.
3.11 + *
3.12 + * The contents of this file are subject to the terms of either the GNU
3.13 + * General Public License Version 2 only ("GPL") or the Common
3.14 + * Development and Distribution License("CDDL") (collectively, the
3.15 + * "License"). You may not use this file except in compliance with the
3.16 + * License. You can obtain a copy of the License at
3.17 + * http://www.netbeans.org/cddl-gplv2.html
3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
3.19 + * specific language governing permissions and limitations under the
3.20 + * License. When distributing the software, include this License Header
3.21 + * Notice in each file and include the License file at
3.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
3.23 + * particular file as subject to the "Classpath" exception as provided
3.24 + * by Oracle in the GPL Version 2 section of the License file that
3.25 + * accompanied this code. If applicable, add the following below the
3.26 + * License Header, with the fields enclosed by brackets [] replaced by
3.27 + * your own identifying information:
3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
3.29 + *
3.30 + * If you wish your version of this file to be governed by only the CDDL
3.31 + * or only the GPL Version 2, indicate your decision by adding
3.32 + * "[Contributor] elects to include this software in this distribution
3.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
3.34 + * single choice of license, a recipient has the option to distribute
3.35 + * your version of this file under either the CDDL, the GPL Version 2 or
3.36 + * to extend the choice of license to its licensees as provided above.
3.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
3.38 + * Version 2 license, then the option applies only if the new code is
3.39 + * made subject to such option by the copyright holder.
3.40 + *
3.41 + * Contributor(s):
3.42 + *
3.43 + * Portions Copyrighted 2014 Sun Microsystems, Inc.
3.44 + */
3.45 +
3.46 +package org.netbeans.modules.dew4nb.services.javac.debugger;
3.47 +
3.48 +import java.util.concurrent.ConcurrentHashMap;
3.49 +import java.util.concurrent.ConcurrentMap;
3.50 +import java.util.concurrent.atomic.AtomicInteger;
3.51 +import org.netbeans.api.annotations.common.CheckForNull;
3.52 +import org.netbeans.api.annotations.common.NonNull;
3.53 +import org.netbeans.api.debugger.DebuggerManager;
3.54 +import org.netbeans.api.debugger.Session;
3.55 +import org.netbeans.modules.dew4nb.endpoint.EndPoint;
3.56 +import org.netbeans.modules.dew4nb.spi.WorkspaceResolver;
3.57 +import org.openide.util.Parameters;
3.58 +
3.59 +/**
3.60 + *
3.61 + * @author Tomas Zezula
3.62 + */
3.63 +final class ActiveSessions {
3.64 +
3.65 + //@GuardedBy("ActiveSessions.class")
3.66 + private static ActiveSessions instance;
3.67 +
3.68 + private final ConcurrentMap<Integer,Data> active;
3.69 + private final AtomicInteger sequencer;
3.70 +
3.71 + private ActiveSessions() {
3.72 + this.active = new ConcurrentHashMap<>();
3.73 + this.sequencer = new AtomicInteger();
3.74 + }
3.75 +
3.76 +
3.77 + int createSession(
3.78 + @NonNull final WorkspaceResolver.Context context,
3.79 + @NonNull final EndPoint.Env env) {
3.80 + Parameters.notNull("context", context); //NOI18N
3.81 + Parameters.notNull("env", env); //NOI18N
3.82 + final int id = sequencer.incrementAndGet();
3.83 + final Session session = DebuggerManager.getDebuggerManager().getCurrentSession();
3.84 + if (active.putIfAbsent(id, new Data(context, env, session)) != null) {
3.85 + throw new IllegalStateException("Trying to reuse active session"); //NOI18N
3.86 + }
3.87 + return id;
3.88 + }
3.89 +
3.90 + @CheckForNull
3.91 + WorkspaceResolver.Context getContext(final int sessionId) {
3.92 + final Data data = active.get(sessionId);
3.93 + return data == null ? null : data.ctx;
3.94 + }
3.95 +
3.96 + @CheckForNull
3.97 + EndPoint.Env getEnv(final int sessionId) {
3.98 + final Data data = active.get(sessionId);
3.99 + return data == null ? null : data.env;
3.100 + }
3.101 +
3.102 + @CheckForNull
3.103 + Session getDebugSession(final int sessionId) {
3.104 + final Data data = active.get(sessionId);
3.105 + return data == null ? null : data.session;
3.106 + }
3.107 +
3.108 +
3.109 + @NonNull
3.110 + static synchronized ActiveSessions getInstance() {
3.111 + if (instance == null) {
3.112 + instance = new ActiveSessions();
3.113 + }
3.114 + return instance;
3.115 + }
3.116 +
3.117 + private static final class Data {
3.118 + final WorkspaceResolver.Context ctx;
3.119 + final EndPoint.Env env;
3.120 + final Session session;
3.121 +
3.122 +
3.123 + private Data(
3.124 + @NonNull final WorkspaceResolver.Context ctx,
3.125 + @NonNull final EndPoint.Env env,
3.126 + @NonNull final Session session) {
3.127 + Parameters.notNull("ctx", ctx); //NOI18N
3.128 + Parameters.notNull("env", env); //NOI18N
3.129 + Parameters.notNull("session", session); //NOI18N
3.130 + this.ctx = ctx;
3.131 + this.env = env;
3.132 + this.session = session;
3.133 + }
3.134 + }
3.135 +
3.136 +}
4.1 --- a/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/debugger/AttachHandler.java Tue Jan 28 10:20:31 2014 +0100
4.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/debugger/AttachHandler.java Tue Jan 28 13:57:53 2014 +0100
4.3 @@ -42,10 +42,7 @@
4.4
4.5 package org.netbeans.modules.dew4nb.services.javac.debugger;
4.6
4.7 -import java.util.concurrent.ConcurrentHashMap;
4.8 -import java.util.concurrent.ConcurrentMap;
4.9 import java.util.concurrent.Executor;
4.10 -import java.util.concurrent.atomic.AtomicInteger;
4.11 import org.netbeans.api.annotations.common.NonNull;
4.12 import org.netbeans.modules.dew4nb.endpoint.AsyncRequestHandler;
4.13 import org.netbeans.modules.dew4nb.endpoint.EndPoint;
4.14 @@ -67,15 +64,11 @@
4.15 @ServiceProvider(service = RequestHandler.class)
4.16 public class AttachHandler extends AsyncRequestHandler<JavacQuery, JavacMessageType> {
4.17
4.18 - private static final Executor RP = new RequestProcessor(AttachHandler.class);
4.19 - private final AtomicInteger idSequencer;
4.20 - private final ConcurrentMap<Integer,WorkspaceResolver.Context> activeSessions;
4.21 + private static final Executor RP = new RequestProcessor(AttachHandler.class);
4.22
4.23
4.24 public AttachHandler() {
4.25 - super(DebugerModels.END_POINT, JavacMessageType.attach, JavacQuery.class);
4.26 - this.idSequencer = new AtomicInteger();
4.27 - this.activeSessions = new ConcurrentHashMap<>();
4.28 + super(DebugerModels.END_POINT, JavacMessageType.attach, JavacQuery.class);
4.29 }
4.30
4.31 @Override
4.32 @@ -105,14 +98,11 @@
4.33 ctx.getWorkspace(),
4.34 "" //NOI18N
4.35 );
4.36 - final FileObject workspace = resolver.resolveFile(serverCtx);
4.37 Status status = Status.not_found;
4.38 int id = -1;
4.39 + final FileObject workspace = resolver.resolveFile(serverCtx);
4.40 if (workspace != null) {
4.41 - id = idSequencer.incrementAndGet();
4.42 - if (activeSessions.putIfAbsent(id, serverCtx) != null) {
4.43 - throw new IllegalStateException("Trying to reuse active session"); //NOI18N
4.44 - }
4.45 + id = ActiveSessions.getInstance().createSession(serverCtx, env);
4.46 status = Status.done;
4.47 }
4.48 final AttachResult attachResult = new AttachResult();
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/debugger/ContinueHandler.java Tue Jan 28 13:57:53 2014 +0100
5.3 @@ -0,0 +1,95 @@
5.4 +/*
5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5.6 + *
5.7 + * Copyright 2014 Oracle and/or its affiliates. All rights reserved.
5.8 + *
5.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
5.10 + * Other names may be trademarks of their respective owners.
5.11 + *
5.12 + * The contents of this file are subject to the terms of either the GNU
5.13 + * General Public License Version 2 only ("GPL") or the Common
5.14 + * Development and Distribution License("CDDL") (collectively, the
5.15 + * "License"). You may not use this file except in compliance with the
5.16 + * License. You can obtain a copy of the License at
5.17 + * http://www.netbeans.org/cddl-gplv2.html
5.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
5.19 + * specific language governing permissions and limitations under the
5.20 + * License. When distributing the software, include this License Header
5.21 + * Notice in each file and include the License file at
5.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
5.23 + * particular file as subject to the "Classpath" exception as provided
5.24 + * by Oracle in the GPL Version 2 section of the License file that
5.25 + * accompanied this code. If applicable, add the following below the
5.26 + * License Header, with the fields enclosed by brackets [] replaced by
5.27 + * your own identifying information:
5.28 + * "Portions Copyrighted [year] [name of copyright owner]"
5.29 + *
5.30 + * If you wish your version of this file to be governed by only the CDDL
5.31 + * or only the GPL Version 2, indicate your decision by adding
5.32 + * "[Contributor] elects to include this software in this distribution
5.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
5.34 + * single choice of license, a recipient has the option to distribute
5.35 + * your version of this file under either the CDDL, the GPL Version 2 or
5.36 + * to extend the choice of license to its licensees as provided above.
5.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
5.38 + * Version 2 license, then the option applies only if the new code is
5.39 + * made subject to such option by the copyright holder.
5.40 + *
5.41 + * Contributor(s):
5.42 + *
5.43 + * Portions Copyrighted 2014 Sun Microsystems, Inc.
5.44 + */
5.45 +
5.46 +package org.netbeans.modules.dew4nb.services.javac.debugger;
5.47 +
5.48 +import org.netbeans.api.annotations.common.NonNull;
5.49 +import org.netbeans.api.debugger.Session;
5.50 +import org.netbeans.api.debugger.jpda.JPDADebugger;
5.51 +import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl;
5.52 +import org.netbeans.modules.dew4nb.endpoint.BasicRequestHandler;
5.53 +import org.netbeans.modules.dew4nb.endpoint.RequestHandler;
5.54 +import org.netbeans.modules.dew4nb.endpoint.Status;
5.55 +import org.netbeans.modules.dew4nb.services.javac.JavacMessageType;
5.56 +import org.netbeans.modules.dew4nb.services.javac.JavacQuery;
5.57 +import org.netbeans.modules.dew4nb.spi.WorkspaceResolver;
5.58 +import org.openide.util.Parameters;
5.59 +import org.openide.util.lookup.ServiceProvider;
5.60 +
5.61 +/**
5.62 + *
5.63 + * @author Tomas Zezula
5.64 + */
5.65 +@ServiceProvider(service=RequestHandler.class)
5.66 +public class ContinueHandler extends BasicRequestHandler<JavacQuery, JavacMessageType, ContinueResult> {
5.67 +
5.68 + public ContinueHandler() {
5.69 + super(DebugerModels.END_POINT, JavacMessageType.cont, JavacQuery.class, ContinueResult.class);
5.70 + }
5.71 +
5.72 + @Override
5.73 + @NonNull
5.74 + protected Status handle(@NonNull final JavacQuery request, @NonNull final ContinueResult response) {
5.75 + Parameters.notNull("request", request); //NOI18N
5.76 + Parameters.notNull("response", response); //NOI18N
5.77 + if (request.getType() != JavacMessageType.cont) {
5.78 + throw new IllegalStateException("Invalid message type: " + request.getType()); //NOI18N
5.79 + }
5.80 + Status status = Status.not_found;
5.81 + final int sessionId = request.getOffset();
5.82 + final WorkspaceResolver.Context ctx = ActiveSessions.getInstance().getContext(sessionId);
5.83 + if (ctx != null) {
5.84 + final Session debugSession = ActiveSessions.getInstance().getDebugSession(sessionId);
5.85 + if (debugSession == null) {
5.86 + throw new IllegalStateException("No debugger session."); //NOI18N
5.87 + }
5.88 + final JPDADebugger jpda = debugSession.lookupFirst(null, JPDADebugger.class);
5.89 + if (!(jpda instanceof JPDADebuggerImpl)) {
5.90 + throw new IllegalStateException("Wrong debugger service."); //NOI18N
5.91 + }
5.92 + ((JPDADebuggerImpl)jpda).resume();
5.93 + status = Status.done;
5.94 + }
5.95 + return status;
5.96 + }
5.97 +
5.98 +}
6.1 --- a/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/debugger/DebugerModels.java Tue Jan 28 10:20:31 2014 +0100
6.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/debugger/DebugerModels.java Tue Jan 28 13:57:53 2014 +0100
6.3 @@ -78,4 +78,12 @@
6.4 static final class SetBreakpointsResultModel {
6.5 }
6.6
6.7 + @Model(className = "ContinueResult", properties = {
6.8 + @Property(name = "status", type = Status.class),
6.9 + @Property(name = "type", type = JavacMessageType.class),
6.10 + @Property(name = "state", type = String.class),
6.11 + })
6.12 + static final class ContinueResultModel {
6.13 + }
6.14 +
6.15 }
7.1 --- a/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/debugger/SetBreakpointsHandler.java Tue Jan 28 10:20:31 2014 +0100
7.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/javac/debugger/SetBreakpointsHandler.java Tue Jan 28 13:57:53 2014 +0100
7.3 @@ -42,12 +42,19 @@
7.4
7.5 package org.netbeans.modules.dew4nb.services.javac.debugger;
7.6
7.7 +import java.util.logging.Level;
7.8 +import java.util.logging.Logger;
7.9 import org.netbeans.api.annotations.common.NonNull;
7.10 +import org.netbeans.api.debugger.DebuggerManager;
7.11 +import org.netbeans.api.debugger.jpda.LineBreakpoint;
7.12 import org.netbeans.modules.dew4nb.endpoint.BasicRequestHandler;
7.13 import org.netbeans.modules.dew4nb.endpoint.RequestHandler;
7.14 import org.netbeans.modules.dew4nb.endpoint.Status;
7.15 import org.netbeans.modules.dew4nb.services.javac.JavacMessageType;
7.16 import org.netbeans.modules.dew4nb.services.javac.JavacQuery;
7.17 +import org.netbeans.modules.dew4nb.spi.WorkspaceResolver;
7.18 +import org.openide.filesystems.FileObject;
7.19 +import org.openide.util.Lookup;
7.20 import org.openide.util.Parameters;
7.21 import org.openide.util.lookup.ServiceProvider;
7.22
7.23 @@ -57,6 +64,8 @@
7.24 */
7.25 @ServiceProvider(service = RequestHandler.class)
7.26 public class SetBreakpointsHandler extends BasicRequestHandler<JavacQuery, JavacMessageType, SetBreakpointsResult> {
7.27 +
7.28 + private static final Logger LOG = Logger.getLogger(SetBreakpointsHandler.class.getName());
7.29
7.30 public SetBreakpointsHandler() {
7.31 super(DebugerModels.END_POINT, JavacMessageType.breakpoints, JavacQuery.class, SetBreakpointsResult.class);
7.32 @@ -69,7 +78,50 @@
7.33 if (request.getType() != JavacMessageType.breakpoints) {
7.34 throw new IllegalStateException("Wrong message type: " + request.getType()); //NOI18N
7.35 }
7.36 - Status status = Status.done;
7.37 + Status status = Status.not_found;
7.38 + final int sessionId = request.getOffset();
7.39 + final WorkspaceResolver.Context ctx = ActiveSessions.getInstance().getContext(sessionId);
7.40 + if (ctx != null) {
7.41 + final String lines = request.getJava();
7.42 + if (lines != null) {
7.43 + final WorkspaceResolver resolver = Lookup.getDefault().lookup(WorkspaceResolver.class);
7.44 + if (resolver == null) {
7.45 + throw new IllegalStateException("No WorkspaceResolver."); //NOI18N
7.46 + }
7.47 + final DebuggerManager dbm = DebuggerManager.getDebuggerManager();
7.48 + for (String line : lines.split(",")) { //NOI18N
7.49 + final int separator = line.lastIndexOf(':'); //NOI18N
7.50 + if (separator > 0 && separator < line.length() - 1) {
7.51 + try {
7.52 + final String path = line.substring(0, separator);
7.53 + final String lineStr = line.substring(separator+1);
7.54 + final int lineNo = Integer.parseInt(lineStr);
7.55 + final FileObject file = resolver.resolveFile(new WorkspaceResolver.Context(ctx.getUser(), ctx.getWorkspace(), path));
7.56 + if (file != null) {
7.57 + final LineBreakpoint lb = LineBreakpoint.create(file.toURL().toExternalForm(), lineNo);
7.58 + dbm.addBreakpoint(lb);
7.59 + } else {
7.60 + LOG.log(
7.61 + Level.WARNING,
7.62 + "Ignoring breakpoint in unresolvable file: {0}", //NOI18N
7.63 + line);
7.64 + }
7.65 + } catch (NumberFormatException nfe) {
7.66 + LOG.log(
7.67 + Level.WARNING,
7.68 + "Ignoring breakpoint with wrong line number: {0}", //NOI18N
7.69 + line);
7.70 + }
7.71 + } else {
7.72 + LOG.log(
7.73 + Level.WARNING,
7.74 + "Ignoring wrong breakpoint: {0}", //NOI18N
7.75 + line);
7.76 + }
7.77 + }
7.78 + }
7.79 + status = Status.done;
7.80 + }
7.81 return status;
7.82 }
7.83