This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 246819
Collapse All | Expand All

(-)a/api.debugger.jpda/apichanges.xml (+19 lines)
Lines 875-880 Link Here
875
        <class package="org.netbeans.api.debugger.jpda" name="JPDAClassType" />
875
        <class package="org.netbeans.api.debugger.jpda" name="JPDAClassType" />
876
        <issue number="237233"/>
876
        <issue number="237233"/>
877
    </change>
877
    </change>
878
    
879
     <change>
880
        <api name="JPDADebuggerAPI"/>
881
        <summary>Add information about native methods into EditorContext.Operation.</summary>
882
        <version major="2" minor="51"/>
883
        <date day="8" month="9" year="2014"/>
884
        <author login="mentlicher"/>
885
        <compatibility addition="yes" source="compatible" binary="compatible"/>
886
        <description>
887
            A new method <code>createMethodOperation()</code>, which takes
888
            <code>boolean isNative</code> is added to <code>EditorContext</code>
889
            class. The <code>EditorContext.Operation</code> has <code>isNative()</code>
890
            method to retrieve that information. The implementation retrieves the
891
            native flag from parser information, therefore there can occur native
892
            methods at runtime, which are not marked as native by this flag.
893
        </description>
894
        <class package="org.netbeans.spi.debugger.jpda" name="EditorContext" />
895
        <issue number="246819"/>
896
    </change>
878
897
879
</changes>
898
</changes>
880
899
(-)a/api.debugger.jpda/manifest.mf (-1 / +1 lines)
Lines 1-6 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.api.debugger.jpda/2
2
OpenIDE-Module: org.netbeans.api.debugger.jpda/2
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/jpda/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/jpda/Bundle.properties
4
OpenIDE-Module-Specification-Version: 2.50
4
OpenIDE-Module-Specification-Version: 2.51
5
OpenIDE-Module-Package-Dependencies: com.sun.jdi[VirtualMachineManager]
5
OpenIDE-Module-Package-Dependencies: com.sun.jdi[VirtualMachineManager]
6
6
(-)a/api.debugger.jpda/src/org/netbeans/spi/debugger/jpda/EditorContext.java (-2 / +43 lines)
Lines 373-379 Link Here
373
                                                    int bytecodeIndex) {
373
                                                    int bytecodeIndex) {
374
        return new Operation(startPosition, endPosition,
374
        return new Operation(startPosition, endPosition,
375
                             methodStartPosition, methodEndPosition,
375
                             methodStartPosition, methodEndPosition,
376
                             methodName, methodClassType, bytecodeIndex);
376
                             methodName, methodClassType, bytecodeIndex, false);
377
    }
378
    
379
    /**
380
     * Creates a method operation.
381
     * @param startPosition The starting position of the operation
382
     * @param endPosition The ending position of the operation
383
     * @param methodStartPosition The starting position of the method name
384
     * @param methodEndPosition The ending position of the method name
385
     * @param methodName The string representation of the method name
386
     * @param methodClassType The class type, which defines this method
387
     * @param bytecodeIndex The bytecode index of this method call
388
     * @param isNative <code>true</code> when the method is determined as a native
389
     *                 method by the parser.
390
     * @since 2.51
391
     */
392
    protected final Operation createMethodOperation(Position startPosition,
393
                                                    Position endPosition,
394
                                                    Position methodStartPosition,
395
                                                    Position methodEndPosition,
396
                                                    String methodName,
397
                                                    String methodClassType,
398
                                                    int bytecodeIndex,
399
                                                    boolean isNative) {
400
        return new Operation(startPosition, endPosition,
401
                             methodStartPosition, methodEndPosition,
402
                             methodName, methodClassType, bytecodeIndex,
403
                             isNative);
377
    }
404
    }
378
    
405
    
379
    /**
406
    /**
Lines 502-507 Link Here
502
        private String methodDescriptor; // TODO: Add API get/set, accessed through reflection in the meantime.
529
        private String methodDescriptor; // TODO: Add API get/set, accessed through reflection in the meantime.
503
        private String methodClassType;
530
        private String methodClassType;
504
        private Variable returnValue;
531
        private Variable returnValue;
532
        private boolean isNative;
505
        
533
        
506
        private List<Operation> nextOperations;
534
        private List<Operation> nextOperations;
507
        
535
        
Lines 520-526 Link Here
520
        Operation(Position startPosition, Position endPosition,
548
        Operation(Position startPosition, Position endPosition,
521
                  Position methodStartPosition, Position methodEndPosition,
549
                  Position methodStartPosition, Position methodEndPosition,
522
                  String methodName, String methodClassType,
550
                  String methodName, String methodClassType,
523
                  int bytecodeIndex) {
551
                  int bytecodeIndex, boolean isNative) {
524
            this.startPosition = startPosition;
552
            this.startPosition = startPosition;
525
            this.endPosition = endPosition;
553
            this.endPosition = endPosition;
526
            this.bytecodeIndex = bytecodeIndex;
554
            this.bytecodeIndex = bytecodeIndex;
Lines 528-533 Link Here
528
            this.methodEndPosition = methodEndPosition;
556
            this.methodEndPosition = methodEndPosition;
529
            this.methodName = methodName;
557
            this.methodName = methodName;
530
            this.methodClassType = methodClassType;
558
            this.methodClassType = methodClassType;
559
            this.isNative = isNative;
531
        }
560
        }
532
        
561
        
533
        synchronized void addNextOperation(Operation next) {
562
        synchronized void addNextOperation(Operation next) {
Lines 580-585 Link Here
580
        }
609
        }
581
        
610
        
582
        /**
611
        /**
612
         * Indicates whether the method was determined as native by the parser.
613
         * It can return <code>false</code> for native methods that are resolved
614
         * during runtime.
615
         * @return <code>true</code> when the method is determined as native by
616
         * the parser.
617
         * @since 2.51
618
         */
619
        public boolean isNative() {
620
            return isNative;
621
        }
622
        
623
        /**
583
         * Get the bytecode index of this operation.
624
         * Get the bytecode index of this operation.
584
         */
625
         */
585
        public int getBytecodeIndex() {
626
        public int getBytecodeIndex() {
(-)a/api.debugger/apichanges.xml (+17 lines)
Lines 501-506 Link Here
501
        <class package="org.netbeans.api.debugger" name="Breakpoint" />
501
        <class package="org.netbeans.api.debugger" name="Breakpoint" />
502
        <issue number="197707"/>
502
        <issue number="197707"/>
503
    </change>
503
    </change>
504
    
505
    <change id="SessionBridge">
506
        <api name="DebuggerCoreAPI"/>
507
        <summary>A session bridge introduced to handle mixed languages debugging.</summary>
508
        <version major="1" minor="48"/>
509
        <date day="8" month="9" year="2014"/>
510
        <author login="mentlicher"/>
511
        <compatibility addition="yes" source="compatible" binary="compatible"/>
512
        <description>
513
            <code>SessionBridge</code> class introduced. This class allows to
514
            suggest that some debug action can be handled by a different debugging
515
            session. The handlers can be registered via implementations of
516
            <code>SessionChanger</code> interface.
517
        </description>
518
        <class package="org.netbeans.api.debugger" name="SessionBridge" />
519
        <issue number="246819"/>
520
    </change>
504
521
505
</changes>
522
</changes>
506
523
(-)a/api.debugger/manifest.mf (-1 / +1 lines)
Lines 1-5 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.api.debugger/1
2
OpenIDE-Module: org.netbeans.api.debugger/1
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/Bundle.properties
4
OpenIDE-Module-Specification-Version: 1.47
4
OpenIDE-Module-Specification-Version: 1.48
5
OpenIDE-Module-Layer: org/netbeans/api/debugger/layer.xml
5
OpenIDE-Module-Layer: org/netbeans/api/debugger/layer.xml
(-)7578d523265c (+218 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2014 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2014 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.api.debugger;
44
45
import java.beans.Customizer;
46
import java.beans.PropertyChangeEvent;
47
import java.beans.PropertyChangeListener;
48
import java.util.ArrayList;
49
import java.util.Collections;
50
import java.util.HashMap;
51
import java.util.List;
52
import java.util.Map;
53
import java.util.Set;
54
import java.util.concurrent.CopyOnWriteArraySet;
55
import org.netbeans.spi.debugger.DebuggerServiceRegistration;
56
57
/**
58
 * Bridge between sessions.
59
 * Use this for mixed languages debugging. Any debug session can suggest to change
60
 * the debugging session for a debug action. A registered implementation of
61
 * {@link SessionChanger} can decide to change the session in order to perform
62
 * the given action.
63
 * <p/>
64
 * In the current implementation, step into action of JPDA debugger is suggested
65
 * for a session change only. The support can be extended according to the future
66
 * requirements.
67
 * 
68
 * @author Martin Entlicher
69
 * @since 1.48
70
 */
71
public final class SessionBridge {
72
    
73
    private static SessionBridge instance;
74
    
75
    private final Map<String, Set<SessionChanger>> sessionChangers = new HashMap<String, Set<SessionChanger>>();
76
    private final List<SessionChanger> lookupSessionChangers;
77
    
78
    private SessionBridge() {
79
        Lookup lookup = new Lookup.MetaInf(null);
80
        final List<? extends SessionChanger> scList = lookup.lookup(null, SessionChanger.class);
81
        ((Customizer) scList).addPropertyChangeListener(new PropertyChangeListener() {
82
            @Override
83
            public void propertyChange(PropertyChangeEvent evt) {
84
                for (SessionChanger sc : lookupSessionChangers) {
85
                    removeSessionChangerListener(sc);
86
                }
87
                lookupSessionChangers.clear();
88
                for (SessionChanger sc : scList) {
89
                    lookupSessionChangers.add(sc);
90
                    addSessionChangerListener(sc);
91
                }
92
            }
93
        });
94
        lookupSessionChangers = new ArrayList<SessionChanger>();
95
        for (SessionChanger sc : scList) {
96
            lookupSessionChangers.add(sc);
97
            addSessionChangerListener(sc);
98
        }
99
    }
100
    
101
    /**
102
     * Get the default instance of SessionBridge.
103
     * @return the default instance
104
     */
105
    public static synchronized SessionBridge getDefault() {
106
        if (instance == null) {
107
            instance = new SessionBridge();
108
        }
109
        return instance;
110
    }
111
    
112
    /**
113
     * Suggest a session change to perform a particular action.
114
     * @param origin The original session suggesting the session change
115
     * @param action An action - a constant from ActionsManager.Action_*
116
     * @param properties Properties describing the current state of the current session before the given action.
117
     *                   The actual properties are specific for the particular session type.
118
     * @return <code>true</code> when the session is changed and another session
119
     *         decided to perform the given action.<br/>
120
     *         <code>false</code> when no other session would like to perform this action.
121
     */
122
    public boolean suggestChange(Session origin, String action, Map<Object, Object> properties) {
123
        Set<SessionChanger> scs;
124
        synchronized (sessionChangers) {
125
            scs = sessionChangers.get(action);
126
        }
127
        if (scs != null) {
128
            for (SessionChanger sc : scs) {
129
                Session newSession = sc.changeSuggested(origin, action, properties);
130
                if (newSession != null) {
131
                    if (DebuggerManager.getDebuggerManager().getCurrentSession() == origin) {
132
                        DebuggerManager.getDebuggerManager().setCurrentSession(newSession);
133
                    }
134
                    return true;
135
                }
136
            }
137
        }
138
        return false;
139
    }
140
    
141
    /**
142
     * Test whether there is some session changer registered for the given action.
143
     * @param action An action - a constant from ActionsManager.Action_*
144
     * @return <code>true</code> when there is some session changer registered
145
     *         for this action, <code>false</code> otherwise.
146
     */
147
    public boolean isChangerFor(String action) {
148
        synchronized (sessionChangers) {
149
            Set<SessionChanger> scs = sessionChangers.get(action);
150
            return scs != null;
151
        }
152
    }
153
    
154
    private void addSessionChangerListener(SessionChanger sc) {
155
        Set<String> actions = sc.getActions();
156
        synchronized (sessionChangers) {
157
            for (String action : actions) {
158
                Set<SessionChanger> scs = sessionChangers.get(action);
159
                if (scs == null) {
160
                    sessionChangers.put(action, Collections.singleton(sc));
161
                } else {
162
                    if (scs.size() == 1) {
163
                        SessionChanger old = scs.iterator().next();
164
                        scs = new CopyOnWriteArraySet<SessionChanger>();
165
                        scs.add(old);
166
                    }
167
                    scs.add(sc);
168
                }
169
            }
170
        }
171
    }
172
    
173
    private void removeSessionChangerListener(SessionChanger sc) {
174
        Set<String> actions = sc.getActions();
175
        synchronized (sessionChangers) {
176
            for (String action : actions) {
177
                Set<SessionChanger> scs = sessionChangers.get(action);
178
                if (scs == null) {
179
                    continue;
180
                }
181
                if (scs.size() == 1) {
182
                    SessionChanger old = scs.iterator().next();
183
                    if (sc.equals(old)) {
184
                        sessionChangers.remove(action);
185
                    }
186
                } else {
187
                    scs.remove(sc);
188
                }
189
            }
190
        }
191
    }
192
    
193
    /**
194
     * Implement this interface to handle a debug session change.
195
     * Register the implementation via {@link DebuggerServiceRegistration} annotation.
196
     */
197
    public static interface SessionChanger {
198
        
199
        /**
200
         * Provide the set of actions that are handled by this implementation.
201
         * @return A set of constants from ActionsManager.Action_*
202
         */
203
        Set<String> getActions();
204
        
205
        /**
206
         * Called when a session suggests a session change for an action.
207
         * @param origin The session suggesting the session change
208
         * @param action The action, a constant from ActionsManager.Action_*
209
         * @param properties Session-specific properties describing the state
210
         *        right before the given action. These are used by a new session
211
         *        to complete the given action.
212
         * @return A new session, or <code>null<code> when this handler decides
213
         *         not to change the debug session for this action.
214
         */
215
        Session changeSuggested(Session origin, String action, Map<Object, Object> properties);
216
    }
217
    
218
}

Return to bug 246819