| <!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" |
| content="text/html; charset=iso-8859-1"> |
| <meta name="GENERATOR" |
| content="Mozilla/4.76 [en] (Windows NT 5.0; U) [Netscape]"> |
| <title>package</title> |
| <!-- |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| |
| --> |
| </head> |
| <body style="color: rgb(0, 0, 0);" link="#0000ee" alink="#0000ee" |
| vlink="#551a8b"> |
| The NetBeans Debugger Core API definition. Debugger Core API interfaces |
| allows to install differrent debugger inlementations to one IDE, and |
| share some UI components among them.<br> |
| <br> |
| <h2><a name="Basic_debugger_model"></a>Basic debugger model<br> |
| </h2> |
| Debugger Core API represents debugger as some tree structure. {@link |
| org.netbeans.api.debugger.DebuggerManager} represents root of this |
| tree. It manages list of {@link org.netbeans.api.debugger.Breakpoint}s, |
| {@link org.netbeans.api.debugger.Watch}es and running {@link |
| org.netbeans.api.debugger.Session}s. All watches and breakpoints |
| registerred here are shared for all running sessions.<br> |
| <br> |
| {@link |
| org.netbeans.api.debugger.Session} represents one process or |
| application running in debug mode. Each Session manages list of |
| supported programming languages. Support for each programming language |
| is represented by some instance of {@link |
| org.netbeans.api.debugger.DebuggerEngine}. DebuggerEngine is a main |
| intergation point for all Debugger Plug-ins. Most of Service Providers |
| (like {@link |
| org.netbeans.spi.debugger.ActionsProvider} or different Models) should |
| be registered for |
| some concrete type of DebuggerEngine.<br> |
| <br> |
| <pre style="background-color: rgb(255, 255, 153);">{@link org.netbeans.api.debugger.DebuggerManager}<br> |<br> |- {@link org.netbeans.api.debugger.Breakpoint}(s)<br> |<br> |- {@link org.netbeans.api.debugger.Watch}(es)<br> |<br> |- {@link org.netbeans.api.debugger.Session}(s) <programming language 1 -> {@link org.netbeans.api.debugger.DebuggerEngine} 1><br> <programming language 2 -> {@link org.netbeans.api.debugger.DebuggerEngine} 2><br> ...<br><br></pre> |
| <br> |
| One DebuggerEngine can manage more than one language. And it can be |
| used for more than one Session. In extreme example, there may be one |
| DebuggerManager only for several different sessions and for many |
| different languages.<br> |
| <br> |
| The only way how to add some language, session or engine to this tree |
| is method {@link |
| org.netbeans.api.debugger.DebuggerManager#startDebugging(DebuggerInfo)}. |
| The only method how to remove something is {@link |
| org.netbeans.api.debugger.DebuggerEngine.Destructor}.<br> |
| <br> |
| <h2><a name="lookups"></a>Exension of basic model - lookups, |
| Meta-inf/debugger<br> |
| </h2> |
| Basic debugger model is very simple, and it should be extended by some |
| additional services (see <a |
| href="../../spi/debugger/package-summary.html">Debugger |
| SPI </a>documentation for default set of additional services). As the |
| Debugger API interfaces should be (and are) final, we use lookup |
| pattern for this purpose. <br> |
| <br> |
| List of 'extensible' interfaces:<br> |
| <ul> |
| <li>{@link org.netbeans.api.debugger.DebuggerManager}: methods {@link |
| org.netbeans.api.debugger.DebuggerManager#lookup(String,Class)} |
| and {@link |
| org.netbeans.api.debugger.DebuggerManager#lookupFirst(String,Class)}</li> |
| <li>{@link org.netbeans.api.debugger.DebuggerInfo}: methods {@link |
| org.netbeans.api.debugger.DebuggerInfo#lookup(String,Class)} and {@link |
| org.netbeans.api.debugger.DebuggerInfo#lookupFirst(String,Class)}</li> |
| <li>{@link org.netbeans.api.debugger.Session}: methods {@link |
| org.netbeans.api.debugger.Session#lookup(String,Class)} and {@link |
| org.netbeans.api.debugger.Session#lookupFirst(String,Class)}</li> |
| <li>{@link org.netbeans.api.debugger.DebuggerEngine}: methods {@link |
| org.netbeans.api.debugger.DebuggerEngine#lookup(String,Class)}, {@link |
| org.netbeans.api.debugger.DebuggerEngine#lookupFirst(String,Class)}, {@link |
| org.netbeans.api.debugger.DebuggerManager#lookup(String,Class)} |
| and {@link |
| org.netbeans.api.debugger.DebuggerManager#lookupFirst(String,Class)}</li> |
| </ul> |
| There are two ways how to registrer services. The first possibility is |
| to put 'live' instance of some service to the interface when a new |
| instance is created. This solution is supported by methods: {@link |
| org.netbeans.api.debugger.DebuggerInfo#create(String,Object[])}, {@link |
| org.netbeans.spi.debugger.SessionProvider#getServices()} and {@link |
| org.netbeans.spi.debugger.DebuggerEngineProvider#getServices()}. Second |
| possibility (and preferred one) is to register service to |
| Meta-inf/debugger folder. The way how to do it is described in <a |
| href="../../spi/debugger/package-summary.html">Debugger |
| SPI </a>documentation.<br> |
| <br> |
| <h2><a name="Debugger_Start_Process"></a>Debugger Start Process</h2> |
| The process which implements starting of debugger in Debugger Core |
| module is very simple. There is one instance of {@link |
| org.netbeans.api.debugger.DebuggerInfo} and {@link |
| org.netbeans.api.debugger.DebuggerManager#startDebugging(DebuggerInfo)} |
| method on the |
| begining of this process. DebuggerInfo determines a set of debugger |
| Sessions to be started:<br> |
| <br> |
| <pre style="background-color: rgb(255, 255, 153);">List sessionProviders = debuggerInfo.lookup (null, SessionsProvider.class);<br></pre> |
| <br> |
| A new instance of {@link |
| org.netbeans.api.debugger.Session} is created for every {@link |
| org.netbeans.spi.debugger.SessionProvider} after that. A set of |
| DebuggerEngines is created for each Session in the second step:<br> |
| <br> |
| <pre style="background-color: rgb(255, 255, 153);">List engineProviders = session.lookup (null, DebuggerEngineProvider.class);<br></pre> |
| <br> |
| Each {@link |
| org.netbeans.spi.debugger.DebuggerEngineProvider} drives creation of |
| one new instance of |
| {@link |
| org.netbeans.api.debugger.DebuggerEngine}. So, the debugger start |
| process creates a tree of |
| new Sessions and new DebuggerEngines and registers them to the |
| DebuggerManager. |
| Thats all.<br> |
| <br> |
| <h2><a name="Debugger_Start_Process_-_advanced"></a>Debugger Start |
| Process - advanced version</h2> |
| Debugger API supports two enhancements to the standard debugger start |
| process:<br> |
| <ol> |
| <li>Start new DebuggerEngine for already existing Session</li> |
| <li>Create a new Session for already existing DebuggerEngine.</li> |
| </ol> |
| {@link |
| org.netbeans.spi.debugger.DelegatingSessionProvider} interface is |
| designed to support first usecase. You should implement and register |
| this interface in Meta-inf/debugger, to delegate on some existing |
| Session. <br> |
| Second usecase is supported by interface {@link |
| org.netbeans.spi.debugger.DelegatingDebuggerEngineProvider}.<br> |
| <br> |
| <h2><a name="Debugger_Actions"></a>Debugger Actions - how does it work</h2> |
| debuggercore-ui module installs some basic set of standard debugger |
| actions to NetBeans toolbar and menu. Debugger actions |
| (javax.swing.Action) are private. Each action is represented by some |
| constant in {@link |
| org.netbeans.api.debugger.ActionsManager} (like {@link |
| org.netbeans.api.debugger.ActionsManager#ACTION_STEP_INTO}). <br> |
| ActionsManager manages list of registered {@link |
| org.netbeans.spi.debugger.ActionProvider}s. It contains mapping between |
| action constant and ActionProvider registerred for this constant. For |
| example:<br> |
| <br> |
| <div style="margin-left: 40px;"><span style="font-style: italic;">instance |
| of DebuggerEngine which represents JPDA debugger contains mapping:</span><br |
| style="font-style: italic;"> |
| <span style="font-style: italic;">ActionsManager.ACTION_STEP_INTO |
| --> JPDAStepIntoActionProvider</span><br> |
| </div> |
| <br> |
| How to implement and register some debugger action:<br> |
| <pre style="background-color: rgb(255, 255, 153);">public class JPDAStepIntoAction extends ActionsProviderSupport {<br><br> JPDAStepIntoAction () {<br> jpdaDebugger.add...Listener (<br> new Listener () {<br> public ...event () {<br> // set state of action here<br> setEnabled ( state );<br> }<br> }<br> );<br> }<br> public boolean doAction (Object action) {<br> // put implementation of action here<br> return true; // action successful<br> }<br>}<br></pre> |
| And JPDAStepIntoAction should be registerred in file:<br> |
| <span style="font-style: italic;">META-INF/debugger/{DebuggerEngineTypeID}/org.netbeans.spi.debugger.ActionsProvider</span><br> |
| <br> |
| Following two diagrams will show how the action system works:<br> |
| <br> |
| <span style="text-decoration: underline;">Diagram 1</span> - what |
| happens when user press Step Into Action:<br> |
| <ol> |
| <li>StepIntoAction calls {@link |
| org.netbeans.api.debugger.ActionsManager#doAction(Object)} for {@link |
| org.netbeans.api.debugger.ActionsManager#ACTION_STEP_INTO}, when its |
| invoked by the user.</li> |
| <li>{@link org.netbeans.api.debugger.ActionsManager} finds proper |
| {@link org.netbeans.spi.debugger.ActionsProvider} registered for given |
| action. Than it calls {@link |
| org.netbeans.spi.debugger.ActionsProvider#doAction(Object)}.</li> |
| <li>{@link org.netbeans.api.debugger.ActionsManager} notifies all |
| {@link org.netbeans.api.debugger.ActionsManagerListener}s about it, when the |
| action is done.<br> |
| </li> |
| </ol> |
| <pre style="background-color: rgb(255, 255, 153);"> <span |
| style="font-weight: bold;">user</span> <span |
| style="font-weight: bold;"> StepIntoAction DebuggerEngine </span><span |
| style="font-weight: bold;">StepInto</span><span |
| style="font-weight: bold;">ActionProvider DebuggerEngineListener<br></span> (javax.swing.Action) | (ActionsProvider) |<span |
| style="font-weight: bold;"><br></span> | | | | <br> o press -> <span |
| style="font-weight: bold;">actionPerformed </span>(...) | | |<br> _|_ action calls | | |<br> | button currentDebuggerEngine. <span |
| style="font-weight: bold;">--></span> <span |
| style="font-weight: bold;">doAction (ACTION_STEP_INTO)</span> | |<br> / \ doAction | | |<br> (ACTION_STEP_INTO) finds ActionsProviders | |<br> | registerred for given action --> <span |
| style="font-weight: bold;">doAction (ACTION_STEP_INTO)</span> |<br> | and calls doAction on them implementation of |<br> | | Step Into Action is here |<br> | | <-- | |<br> | fires PROP_ACTION_PERFORMED | |<br> | | <span |
| style="font-weight: bold;">--></span> -|-> <span |
| style="font-weight: bold;">actionPerformed</span> (..)<br> | | | listener impl.<br> | <-- <-|- <-|- <--|<br> | | | |<br></pre> |
| <br> |
| <span style="text-decoration: underline;">Diagram 2</span> - what |
| happens when the state of Step Into Action is changed:<br> |
| <ol> |
| <li>Debugger implementation should recognize that the state of Step |
| Into action should be changed, and it should notify |
| StepIntoActionProvider about it.</li> |
| <li>StepIntoActionProvider should fire {@link |
| org.netbeans.spi.debugger.ActionsProviderListener#actionStateChange(Object,boolean)} |
| for {@link org.netbeans.api.debugger.ActionsManager#ACTION_STEP_INTO}.</li> |
| <li>{@link org.netbeans.api.debugger.DebuggerEngine} is listenning on |
| all installed {@link org.netbeans.spi.debugger.ActionsProvider}s and |
| fires all action state changes using {@link |
| org.netbeans.api.debugger.DebuggerEngineListener#actionStateChanged(Object,boolean)}.</li> |
| <li>StepIntoAction listens on {@link |
| org.netbeans.api.debugger.DebuggerEngine}, and it updates its state |
| when some actionStateChanged is fired.<br> |
| </li> |
| </ol> |
| <pre style="background-color: rgb(255, 255, 153);"> <span |
| style="font-weight: bold;"> debugger</span> <span |
| style="font-weight: bold;"> StepInto</span><span |
| style="font-weight: bold;">ActionProvider</span><span |
| style="font-weight: bold;"> DebuggerEngine.ActionsProviderListener </span><span |
| style="font-weight: bold;">StepIntoAction.DebuggerEngineListener</span><span |
| style="font-weight: bold;"></span><br> (ActionsProvider) | (javax.swing.Action) <span |
| style="font-weight: bold;"><br></span> | | |<br> _ state of -> fire action state | |<br> |?| action change --> <b>actionStateChange</b> (ACTION_STEP_INTO, enabled) |<br> ¯ should be | | |<br> changed | fire DebuggerEngineListener |<br> | actionStateChanged --> <span |
| style="font-weight: bold;">actionStateChanged</span><br> | | updates a state<br> | | of action<br> |<-- <-|- <span |
| style="font-weight: bold;"><--</span> |<br></pre> |
| <br> |
| </body> |
| </html> |