View | Details | Raw Unified | Return to bug 186256 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMProvider.java (-17 / +33 lines)
Lines 1-13 Link Here
1
/*******************************************************************************
1
/**
2
 * Copyright (c) 2006 Wind River Systems and others.
2
 * Copyright (c) 2006 Wind River Systems and others. All rights reserved. This program and
3
 * All rights reserved. This program and the accompanying materials
3
 * the accompanying materials are made available under the terms of the Eclipse Public
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * License v1.0 which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
5
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
6
 * 
8
 * Contributors:
7
 * Contributors: Wind River Systems - initial API and implementation
9
 *     Wind River Systems - initial API and implementation
8
 */
10
 *******************************************************************************/
11
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
9
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
12
10
13
import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode;
11
import org.eclipse.dd.dsf.debug.ui.viewmodel.DebugViewSelectionRootLayoutNode;
Lines 17-35 Link Here
17
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
15
import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode;
18
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider;
16
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider;
19
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
17
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
18
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory;
20
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
19
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
21
20
22
/**
23
 * 
24
 */
25
@SuppressWarnings("restriction")
21
@SuppressWarnings("restriction")
26
public class VariableVMProvider extends AbstractDMVMProvider {
22
public class VariableVMProvider extends AbstractDMVMProvider implements
27
    public VariableVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) {
23
		IColumnPresentationFactory {
24
25
	public VariableVMProvider(AbstractVMAdapter adapter, IPresentationContext context, DsfSession session) {
28
        super(adapter, context, session);
26
        super(adapter, context, session);
29
        IVMRootLayoutNode debugViewSelectionNode = new DebugViewSelectionRootLayoutNode(this); 
27
        
30
        IVMLayoutNode localsNode = new LocalsLayoutNode(this, getSession());
28
        /*
31
        debugViewSelectionNode.setChildNodes(new IVMLayoutNode[] { localsNode });
29
         *  Create the top level node to deal with the root selection.
32
        setRootLayoutNode(debugViewSelectionNode);
30
         */
31
        IVMRootLayoutNode debugViewSelection = new DebugViewSelectionRootLayoutNode(this);
32
        
33
        /*
34
         *  Create the local variables nodes next. They represent the first level shown in the view.
35
         */
36
        IVMLayoutNode localsNode = new VariableLocalsLayoutNode(this, getSession());
37
        debugViewSelection.setChildNodes(new IVMLayoutNode[] { localsNode });
38
        
39
        /*
40
         * Create the next level which represents members of structs/unions/enums and elements of arrays.
41
         */
42
        IVMLayoutNode subExpressioNode = new VariableSubExpressionsLayoutNode(this, getSession());
43
        localsNode.setChildNodes(new IVMLayoutNode[] { subExpressioNode });
44
        
45
        /*
46
         *  Now set this schema set as the layout set.
47
         */
48
        setRootLayoutNode(debugViewSelection);
33
    }
49
    }
34
50
35
    @Override
51
    @Override
(-)src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/LocalsLayoutNode.java (-94 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
12
13
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
14
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
15
import org.eclipse.dd.dsf.datamodel.IDMContext;
16
import org.eclipse.dd.dsf.datamodel.IDMEvent;
17
import org.eclipse.dd.dsf.debug.service.IRegisters;
18
import org.eclipse.dd.dsf.debug.service.IRunControl;
19
import org.eclipse.dd.dsf.debug.service.IStack;
20
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
21
import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext;
22
import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData;
23
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
24
import org.eclipse.dd.dsf.service.DsfSession;
25
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
26
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
27
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
28
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
29
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
30
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
31
32
@SuppressWarnings("restriction")
33
public class LocalsLayoutNode extends AbstractDMVMLayoutNode<IVariableDMData> {
34
35
    public LocalsLayoutNode(AbstractVMProvider provider, DsfSession session) {
36
        super(provider, session, IStack.IVariableDMContext.class);
37
    }
38
    
39
    @Override
40
    protected void updateElementsInSessionThread(final IChildrenUpdate update) {
41
        if (!checkService(IRegisters.class, null, update)) return;
42
        
43
        final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class) ;
44
        
45
        if (frameDmc != null) {
46
            getServicesTracker().getService(IStack.class).getArguments(
47
                frameDmc,
48
                new DataRequestMonitor<IVariableDMContext[]>(getSession().getExecutor(), null) { 
49
                    @Override
50
                    public void handleCompleted() {
51
                        if (!getStatus().isOK()) {
52
                            update.done();
53
                            return;
54
                        }
55
                        fillUpdateWithVMCs(update, getData());
56
                        update.done();
57
                    }}); 
58
        } else {
59
            handleFailedUpdate(update);
60
        }          
61
        
62
    }
63
    
64
    @Override
65
    protected void fillColumnLabel(IDMContext<IVariableDMData> dmContext, IVariableDMData dmData,
66
                                   String columnId, int idx, ILabelUpdate update) 
67
    {
68
        if (IDebugVMConstants.COLUMN_ID__NAME.equals(columnId)) {
69
            update.setLabel(dmData.getName(), idx);
70
        } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(columnId)) {
71
            update.setLabel(dmData.getValue(), idx);
72
        } else {
73
            update.setLabel("", idx); //$NON-NLS-1$
74
        }
75
    }
76
    
77
    @Override
78
    protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) {
79
        if (e instanceof IRunControl.ISuspendedDMEvent) {
80
            return IModelDelta.CONTENT;
81
        }
82
        return IModelDelta.NO_CHANGE;
83
    }
84
85
    @Override
86
    protected void buildDeltaForDMEvent(IDMEvent<?> e, VMDelta parent, int nodeOffset, RequestMonitor rm) {
87
        if (e instanceof IRunControl.ISuspendedDMEvent) {
88
            // Create a delta that the whole register group has changed.
89
            parent.addFlags(IModelDelta.CONTENT);
90
        } 
91
        
92
        super.buildDeltaForDMEvent(e, parent, nodeOffset, rm);
93
    }
94
}
(-)src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableLocalsLayoutNode.java (+341 lines)
Added Link Here
1
/**
2
 * Copyright (c) 2006 Wind River Systems and others. All rights reserved. This program and
3
 * the accompanying materials are made available under the terms of the Eclipse Public
4
 * License v1.0 which accompanies this distribution, and is available at
5
 * http://www.eclipse.org/legal/epl-v10.html
6
 * 
7
 * Contributors: Wind River Systems - initial API and implementation
8
 */
9
10
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
11
12
import java.util.ArrayList;
13
import java.util.List;
14
15
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
16
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
17
import org.eclipse.dd.dsf.concurrent.MultiRequestMonitor;
18
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
19
import org.eclipse.dd.dsf.datamodel.IDMEvent;
20
import org.eclipse.dd.dsf.datamodel.IDMService;
21
import org.eclipse.dd.dsf.debug.service.IExpressions;
22
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
23
import org.eclipse.dd.dsf.debug.service.IRunControl;
24
import org.eclipse.dd.dsf.debug.service.IStack;
25
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext;
26
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData;
27
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
28
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData;
29
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
30
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
31
import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMContext;
32
import org.eclipse.dd.dsf.debug.service.IStack.IVariableDMData;
33
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
34
import org.eclipse.dd.dsf.service.DsfSession;
35
import org.eclipse.dd.dsf.service.IDsfService;
36
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
37
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
38
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
39
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
40
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
41
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
42
43
@SuppressWarnings("restriction")
44
public class VariableLocalsLayoutNode extends AbstractDMVMLayoutNode<IExpressionDMData> {
45
46
    public VariableLocalsLayoutNode(AbstractVMProvider provider, DsfSession session) {
47
        super(provider, session, IExpressions.IExpressionDMContext.class);
48
    }
49
50
    /**
51
     * We override this method because we now need to perform an extra level of data fetch to get the
52
     * formatted value of the expression.
53
     * 
54
     * @return void
55
     */
56
    @Override
57
    protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
58
        for (final ILabelUpdate update : updates) {
59
            
60
            final IExpressionDMContext dmc = findDmcInPath(update.getElementPath(), IExpressions.IExpressionDMContext.class);
61
            
62
            ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData(
63
                dmc, 
64
                new DataRequestMonitor<IExpressionDMData>(getSession().getExecutor(), null) { 
65
                    @Override
66
                    protected void handleCompleted() {
67
                        // Check that the request was evaluated and data is still valid.  The request could
68
                        // fail if the state of the  service changed during the request, but the view model
69
                        // has not been updated yet.
70
                        
71
                        if (!getStatus().isOK() || !getData().isValid()) {
72
                            assert getStatus().isOK() || 
73
                                   getStatus().getCode() != IDsfService.INTERNAL_ERROR || 
74
                                   getStatus().getCode() != IDsfService.NOT_SUPPORTED;
75
                            handleFailedUpdate(update);
76
                            return;
77
                        }
78
                        
79
                        // If columns are configured, extract the selected values for each understood column.
80
                        // First, we fill all of those columns which can be filled without extra data mining.
81
                        // We also note if we  do have to do extra data mining.  Any columns need to set the
82
                        // processing flag so we know we have further work to do.  If there are more columns
83
                        // which need data extraction they need to be added in both "for" loops.
84
85
                        String[] localColumns = update.getPresentationContext().getColumns();
86
                        if (localColumns == null)
87
                            localColumns = new String[] { null };
88
                        
89
                        boolean weAreExtractingFormattedData = false;
90
                        
91
                        for (int idx = 0; idx < localColumns.length; idx++) {
92
                            if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) {
93
                                update.setLabel(getData().getName(), idx);
94
                            } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
95
                                weAreExtractingFormattedData = true;
96
                            } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) {
97
                                update.setLabel("", idx); //$NON-NLS-1$
98
                            }
99
                        }
100
                        
101
                        if ( ! weAreExtractingFormattedData ) {
102
                            update.done();
103
                        } else {
104
                            for (int idx = 0; idx < localColumns.length; idx++) {
105
                                if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
106
                                    updateFormattedExpressionValue(update, idx, dmc);
107
                                }
108
                            }
109
                        }
110
                    }
111
                }
112
            );
113
        }
114
    }
115
116
    
117
    /**
118
     *  Private data access routine which performs the extra level of data access needed to
119
     *  get the formatted data value for a specific register.
120
     */
121
    private void updateFormattedExpressionValue(final ILabelUpdate update, final int labelIndex,
122
                                                final IExpressionDMContext dmc)
123
    {
124
        final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
125
        /*
126
         *  PREFPAGE : We are using a default format until the preference page is created
127
         *  
128
         *  First select the format to be used. This involves checking so see that the preference
129
         *  page format is supported by the register service. If the format is not supported then 
130
         *  we will pick the first available format.
131
         */
132
        
133
        final String preferencePageFormatId = IFormattedValues.NATURAL_FORMAT;
134
        
135
        expressionService.getAvailableFormattedValues(
136
            dmc,
137
            new DataRequestMonitor<String[]>(getSession().getExecutor(), null) {
138
                @Override
139
                public void handleCompleted() {
140
                    if (!getStatus().isOK()) {
141
                        handleFailedUpdate(update);
142
                        return;
143
                    }
144
                    
145
                    /*
146
                     *  See if the desired format is supported.
147
                     */
148
                    String[] formatIds = getData();
149
                    String   finalFormatId = IFormattedValues.NATURAL_FORMAT;
150
                    boolean  requestedFormatIsSupported = false;
151
                    
152
                    for ( String fId : formatIds ) {
153
                        if ( preferencePageFormatId.equals(fId) ) {
154
                            // The desired format is supported.
155
156
                            finalFormatId = preferencePageFormatId;
157
                            requestedFormatIsSupported = true;
158
                            break;
159
                        }
160
                    }
161
                    
162
                    if ( ! requestedFormatIsSupported ) {
163
                        /*
164
                         *  Desired format is not supported. If there are any formats supported
165
                         *  then use the first available.
166
                         */
167
                        if ( formatIds.length != 0 ) {
168
                            finalFormatId = formatIds[0];
169
                        }
170
                        else {
171
                            // Expression service does not support any format.
172
                            
173
                            handleFailedUpdate(update);
174
                            return;
175
                        }
176
                    }
177
                    
178
                    /*
179
                     *  Format has been validated. Get the formatted value.
180
                     */
181
                    FormattedValueDMContext valueDmc = expressionService.getFormattedValue(dmc, finalFormatId);
182
                    
183
                    expressionService.getModelData(
184
                        valueDmc, 
185
                        new DataRequestMonitor<FormattedValueDMData>(getSession().getExecutor(), null) {
186
                            @Override
187
                            public void handleCompleted() {
188
                                if (!getStatus().isOK()) {
189
                                    handleFailedUpdate(update);
190
                                    return;
191
                                }
192
193
                                /*
194
                                 *  Fill the label/column with the properly formatted data value.
195
                                 */
196
                                update.setLabel(getData().getFormattedValue(), labelIndex);
197
                                update.done();
198
                            }
199
                        }
200
                    );
201
                }
202
            }
203
        );
204
    }
205
206
    
207
    @Override
208
    protected void updateElementsInSessionThread(final IChildrenUpdate update) {
209
210
        // ISSUE: Do we need to explicitly get the IExecutionDMContext and ISymbolDMContext since they
211
        // should be in the parent chain of the IFrameDMContext object?
212
        
213
        final IExecutionDMContext execDmc =
214
            findDmcInPath(update.getElementPath(), IExecutionDMContext.class);
215
        final IFrameDMContext frameDmc =
216
            findDmcInPath(update.getElementPath(), IFrameDMContext.class);
217
        //final ISymbolDMContext symbolDmc =
218
        //    findDmcInPath(update.getElementPath(), ISymbolDMContext.class);
219
220
        // Get the services we need to use.
221
        
222
        final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
223
        final IStack stackFrameService = getServicesTracker().getService(IStack.class);
224
        
225
        if (execDmc == null || frameDmc == null || expressionService == null || stackFrameService == null) {
226
            handleFailedUpdate(update);
227
            return;
228
        }
229
230
        final DsfExecutor dsfExecutor = getSession().getExecutor();
231
        
232
        // Call IStack.getLocals() to get an array of IVariableDMContext objects representing the local
233
        // variables in the stack frame represented by frameDmc.
234
         
235
        final DataRequestMonitor<IVariableDMContext[]> rm =
236
            new DataRequestMonitor<IVariableDMContext[]>(dsfExecutor, null) {
237
                @Override
238
                public void handleCompleted() {
239
                    if (!getStatus().isOK()) {
240
                        handleFailedUpdate(update);
241
                        return;
242
                    }
243
                    
244
                    // For each IVariableDMContext object returned by IStack.getLocals(), call
245
                    // MIStackFrameService.getModelData() to get the IVariableDMData object.  This requires
246
                    // a MultiRequestMonitor object.
247
                    
248
                    // First, get the data model context objects for the local variables.
249
                    
250
                    IVariableDMContext[] localsDMCs = getData();
251
                    
252
                    if (localsDMCs == null) {
253
                        handleFailedUpdate(update);
254
                        return;
255
                    }
256
                    
257
                    // Create a List in which we store the DM data objects for the local variables.  This is
258
                    // necessary because there is no MultiDataRequestMonitor. :)
259
                    
260
                    final List<IVariableDMData> localsDMData = new ArrayList<IVariableDMData>();
261
                    
262
                    // Create the MultiRequestMonitor to handle completion of the set of getModelData() calls.
263
                    
264
                    final MultiRequestMonitor<DataRequestMonitor<IVariableDMData>> mrm =
265
                        new MultiRequestMonitor<DataRequestMonitor<IVariableDMData>>(dsfExecutor, null) {
266
                            @Override
267
                            public void handleCompleted() {
268
                                // Now that all the calls to getModelData() are complete, we create an
269
                                // IExpressionDMContext object for each local variable name, saving them all
270
                                // in an array.
271
                                
272
                                IExpressionDMContext[] expressionDMCs = new IExpressionDMContext[localsDMData.size()];
273
                                
274
                                int i = 0;
275
                                
276
                                for (IVariableDMData localDMData : localsDMData) {
277
                                    expressionDMCs[i++] = expressionService.createExpression(frameDmc, localDMData.getName());
278
                                }
279
280
                                // Lastly, we fill the update from the array of view model context objects
281
                                // that reference the ExpressionDMC objects for the local variables.  This is
282
                                // the last code to run for a given call to updateElementsInSessionThread().
283
                                // We can now leave anonymous-inner-class hell.
284
285
                                fillUpdateWithVMCs(update, expressionDMCs);
286
                                update.done();
287
                            }
288
                    };
289
                    
290
                    // Perform a set of getModelData() calls, one for each local variable's data model
291
                    // context object.  In the handleCompleted() method of the DataRequestMonitor, add the
292
                    // IVariableDMData object to the localsDMData List for later processing (see above).
293
                    
294
                    for (IVariableDMContext localDMC : localsDMCs) {
295
                        DataRequestMonitor<IVariableDMData> rm =
296
                            new DataRequestMonitor<IVariableDMData>(dsfExecutor, null) {
297
                                @Override
298
                                public void handleCompleted() {
299
                                    localsDMData.add(getData());
300
                                    mrm.requestMonitorDone(this);
301
                                }
302
                        };
303
                        
304
                        mrm.add(rm);
305
                        
306
                        stackFrameService.getModelData(localDMC, rm);
307
                    }
308
                }
309
        };
310
311
        // Make the asynchronous call to IStack.getLocals().  The results are processed in the
312
        // DataRequestMonitor.handleCompleted() above.
313
314
        stackFrameService.getLocals(frameDmc, rm);
315
    }
316
317
    @Override
318
    protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) {
319
        if (e instanceof IRunControl.ISuspendedDMEvent) {
320
            return IModelDelta.CONTENT;
321
            // } else if (e instanceof IRegisters.IRegisterChangedDMEvent) {
322
            // return IModelDelta.STATE;
323
        }
324
        return IModelDelta.NO_CHANGE;
325
    }
326
327
    @Override
328
    protected void buildDeltaForDMEvent(IDMEvent<?> e, VMDelta parent,
329
            int nodeOffset, RequestMonitor requestMonitor) {
330
        if (e instanceof IRunControl.ISuspendedDMEvent) {
331
            // Create a delta that the whole register group has changed.
332
            parent.addFlags(IModelDelta.CONTENT);
333
        }
334
        // if (e instanceof IRegisters.IRegisterChangedDMEvent) {
335
        // parent.addNode(new
336
        // DMVMContext(((IRegisters.IRegisterChangedDMEvent)e).getDMContext()),
337
        // IModelDelta.STATE);
338
        // }
339
        super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor);
340
    }
341
}
(-)src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableSubExpressionsLayoutNode.java (+297 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.dd.dsf.debug.ui.viewmodel.variable;
12
13
import java.util.Iterator;
14
import java.util.List;
15
16
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
17
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
18
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
19
import org.eclipse.dd.dsf.datamodel.IDMEvent;
20
import org.eclipse.dd.dsf.datamodel.IDMService;
21
import org.eclipse.dd.dsf.debug.service.IExpressions;
22
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
23
import org.eclipse.dd.dsf.debug.service.IRunControl;
24
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext;
25
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData;
26
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
27
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData;
28
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
29
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
30
import org.eclipse.dd.dsf.debug.ui.viewmodel.IDebugVMConstants;
31
import org.eclipse.dd.dsf.service.DsfSession;
32
import org.eclipse.dd.dsf.service.IDsfService;
33
import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider;
34
import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode;
35
import org.eclipse.dd.dsf.ui.viewmodel.VMDelta;
36
import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode;
37
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
38
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
39
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
40
41
@SuppressWarnings("restriction")
42
public class VariableSubExpressionsLayoutNode extends AbstractDMVMLayoutNode<IExpressionDMData> {
43
44
    public VariableSubExpressionsLayoutNode(AbstractVMProvider provider, DsfSession session) {
45
        super(provider, session, IExpressions.IExpressionDMContext.class);
46
    }
47
    
48
    /** 
49
     * List of child nodes containing only a reference to this.  This is what enables the view model
50
     * provider to know about the recursive nature of subexpression nodes.
51
     */
52
    private final IVMLayoutNode[] fChildLayoutNodes = { this };
53
    
54
    @Override
55
    public IVMLayoutNode[] getChildLayoutNodes() {
56
        return fChildLayoutNodes;
57
    }
58
59
    
60
    /**
61
     * We override this method because we now need to perform an extra level of data fetch to get the
62
     * formatted value of the expression.
63
     * 
64
     * @return void
65
     */
66
    @Override
67
    protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
68
        for (final ILabelUpdate update : updates) {
69
            
70
            final IExpressionDMContext dmc = findDmcInPath(update.getElementPath(), IExpressions.IExpressionDMContext.class);
71
            
72
            ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData(
73
                dmc, 
74
                new DataRequestMonitor<IExpressionDMData>(getSession().getExecutor(), null) { 
75
                    @Override
76
                    protected void handleCompleted() {
77
                        // Check that the request was evaluated and data is still valid.  The request could
78
                        // fail if the state of the  service changed during the request, but the view model
79
                        // has not been updated yet.
80
                        
81
                        if (!getStatus().isOK() || !getData().isValid()) {
82
                            assert getStatus().isOK() || 
83
                                   getStatus().getCode() != IDsfService.INTERNAL_ERROR || 
84
                                   getStatus().getCode() != IDsfService.NOT_SUPPORTED;
85
                            handleFailedUpdate(update);
86
                            return;
87
                        }
88
                        
89
                        // If columns are configured, extract the selected values for each understood column.
90
                        // First, we fill all of those columns which can be filled without extra data mining.
91
                        // We also note if we  do have to do extra data mining.  Any columns need to set the
92
                        // processing flag so we know we have further work to do.  If there are more columns
93
                        // which need data extraction they need to be added in both "for" loops.
94
95
                        String[] localColumns = update.getPresentationContext().getColumns();
96
                        if (localColumns == null)
97
                            localColumns = new String[] { null };
98
                        
99
                        boolean weAreExtractingFormattedData = false;
100
                        
101
                        for (int idx = 0; idx < localColumns.length; idx++) {
102
                            if (IDebugVMConstants.COLUMN_ID__NAME.equals(localColumns[idx])) {
103
                                update.setLabel(getData().getName(), idx);
104
                            } else if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
105
                                weAreExtractingFormattedData = true;
106
                            } else if (IDebugVMConstants.COLUMN_ID__DESCRIPTION.equals(localColumns[idx])) {
107
                                update.setLabel("", idx); //$NON-NLS-1$
108
                            }
109
                        }
110
                        
111
                        if ( ! weAreExtractingFormattedData ) {
112
                            update.done();
113
                        } else {
114
                            for (int idx = 0; idx < localColumns.length; idx++) {
115
                                if (IDebugVMConstants.COLUMN_ID__VALUE.equals(localColumns[idx])) {
116
                                    updateFormattedExpressionValue(update, idx, dmc);
117
                                }
118
                            }
119
                        }
120
                    }
121
                }
122
            );
123
        }
124
    }
125
126
    
127
    /**
128
     *  Private data access routine which performs the extra level of data access needed to
129
     *  get the formatted data value for a specific register.
130
     */
131
    private void updateFormattedExpressionValue(final ILabelUpdate update, final int labelIndex,
132
                                                final IExpressionDMContext dmc)
133
    {
134
        final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
135
        /*
136
         *  PREFPAGE : We are using a default format until the preference page is created
137
         *  
138
         *  First select the format to be used. This involves checking so see that the preference
139
         *  page format is supported by the register service. If the format is not supported then 
140
         *  we will pick the first available format.
141
         */
142
        
143
        final String preferencePageFormatId = IFormattedValues.NATURAL_FORMAT;
144
        
145
        expressionService.getAvailableFormattedValues(
146
            dmc,
147
            new DataRequestMonitor<String[]>(getSession().getExecutor(), null) {
148
                @Override
149
                public void handleCompleted() {
150
                    if (!getStatus().isOK()) {
151
                        handleFailedUpdate(update);
152
                        return;
153
                    }
154
                    
155
                    /*
156
                     *  See if the desired format is supported.
157
                     */
158
                    String[] formatIds = getData();
159
                    String   finalFormatId = IFormattedValues.NATURAL_FORMAT;
160
                    boolean  requestedFormatIsSupported = false;
161
                    
162
                    for ( String fId : formatIds ) {
163
                        if ( preferencePageFormatId.equals(fId) ) {
164
                            // The desired format is supported.
165
166
                            finalFormatId = preferencePageFormatId;
167
                            requestedFormatIsSupported = true;
168
                            break;
169
                        }
170
                    }
171
                    
172
                    if ( ! requestedFormatIsSupported ) {
173
                        /*
174
                         *  Desired format is not supported. If there are any formats supported
175
                         *  then use the first available.
176
                         */
177
                        if ( formatIds.length != 0 ) {
178
                            finalFormatId = formatIds[0];
179
                        }
180
                        else {
181
                            // Expression service does not support any format.
182
                            
183
                            handleFailedUpdate(update);
184
                            return;
185
                        }
186
                    }
187
                    
188
                    /*
189
                     *  Format has been validated. Get the formatted value.
190
                     */
191
                    FormattedValueDMContext valueDmc = expressionService.getFormattedValue(dmc, finalFormatId);
192
                    
193
                    expressionService.getModelData(
194
                        valueDmc, 
195
                        new DataRequestMonitor<FormattedValueDMData>(getSession().getExecutor(), null) {
196
                            @Override
197
                            public void handleCompleted() {
198
                                if (!getStatus().isOK()) {
199
                                    handleFailedUpdate(update);
200
                                    return;
201
                                }
202
203
                                /*
204
                                 *  Fill the label/column with the properly formatted data value.
205
                                 */
206
                                update.setLabel(getData().getFormattedValue(), labelIndex);
207
                                update.done();
208
                            }
209
                        }
210
                    );
211
                }
212
            }
213
        );
214
    }
215
    
216
    
217
    @Override
218
    protected void updateElementsInSessionThread(final IChildrenUpdate update) {
219
        // Get the data model context object for the current node in the hierarchy.
220
        
221
        final IExpressionDMContext expressionDMC = findDmcInPath(update.getElementPath(), IExpressionDMContext.class);
222
223
        // ISSUE: Do we need to explicitly get the IExecutionDMContext and ISymbolDMContext since they
224
        // should be in the parent chain of the IFrameDMContext object?
225
        
226
        final IExecutionDMContext execDmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class);
227
        final IFrameDMContext frameDmc = findDmcInPath(update.getElementPath(), IFrameDMContext.class);
228
        //final ISymbolDMContext symbolDmc = findDmcInPath(update.getElementPath(), ISymbolDMContext.class);
229
230
        // Get the services we need to use.
231
        
232
        final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
233
        
234
        if (execDmc == null || frameDmc == null || expressionService == null) {
235
            handleFailedUpdate(update);
236
            return;
237
        }
238
239
        final DsfExecutor dsfExecutor = getSession().getExecutor();
240
        
241
        // Call IExpressions.getSubExpressions() to get an Iterable of IExpressionDMContext objects representing
242
        // the sub-expressions of the expression represented by the current expression node.
243
        
244
        final DataRequestMonitor<Iterable<IExpressionDMContext>> rm =
245
            new DataRequestMonitor<Iterable<IExpressionDMContext>>(dsfExecutor, null) {
246
                @Override
247
                public void handleCompleted() {
248
                    if (!getStatus().isOK()) {
249
                        handleFailedUpdate(update);
250
                        return;
251
                    }
252
                    
253
                    // Fill the update with the the IExpressionDMContext objects returned by
254
                    // IExpressions.getSubExpressions().
255
                    
256
                    List<IExpressionDMContext> subExpressionDMCList = (List<IExpressionDMContext>)getData();
257
                    IExpressionDMContext[] subExpressionDMCArray = new IExpressionDMContext[subExpressionDMCList.size()];
258
                    Iterator<IExpressionDMContext> iter = subExpressionDMCList.iterator();
259
260
                    int i = 0;
261
                    while (iter.hasNext()) {
262
                        subExpressionDMCArray[i++] = iter.next();
263
                    }
264
265
                    fillUpdateWithVMCs(update, subExpressionDMCArray);
266
                    update.done();
267
                }
268
        };
269
270
        // Make the asynchronous call to IExpressions.getSubExpressions().  The results are processed in the
271
        // DataRequestMonitor.handleCompleted() above.
272
273
        expressionService.getSubExpressions(expressionDMC, rm);
274
    }
275
    
276
    @Override
277
    protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) {
278
        if (e instanceof IRunControl.ISuspendedDMEvent) {
279
            return IModelDelta.CONTENT;
280
//        } else if (e instanceof IRegisters.IExpressionsChangedDMEvent) {
281
//            return IModelDelta.STATE;
282
        } 
283
        return IModelDelta.NO_CHANGE;
284
    }
285
286
    @Override
287
    protected void buildDeltaForDMEvent(IDMEvent<?> e, VMDelta parent, int nodeOffset, RequestMonitor requestMonitor) {
288
        if (e instanceof IRunControl.ISuspendedDMEvent) {
289
            // Create a delta that the whole register group has changed.
290
            parent.addFlags(IModelDelta.CONTENT);
291
        } 
292
//        if (e instanceof IRegisters.IRegisterChangedDMEvent) {
293
//            parent.addNode( new DMVMContext(((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE );
294
//        } 
295
        super.buildDeltaForDMEvent(e, parent, nodeOffset, requestMonitor);
296
    }
297
}

Return to bug 186256