KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > views > memory > renderings > AsyncTableRenderingCellModifier


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation 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  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.debug.internal.ui.views.memory.renderings;
13
14 import java.math.BigInteger JavaDoc;
15
16 import org.eclipse.core.runtime.IProgressMonitor;
17 import org.eclipse.core.runtime.IStatus;
18 import org.eclipse.core.runtime.Status;
19 import org.eclipse.core.runtime.jobs.Job;
20 import org.eclipse.debug.core.DebugException;
21 import org.eclipse.debug.core.model.IMemoryBlock;
22 import org.eclipse.debug.core.model.IMemoryBlockExtension;
23 import org.eclipse.debug.core.model.MemoryByte;
24 import org.eclipse.debug.internal.ui.DebugUIMessages;
25 import org.eclipse.debug.internal.ui.DebugUIPlugin;
26 import org.eclipse.debug.internal.ui.memory.provisional.AbstractAsyncTableRendering;
27 import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
28 import org.eclipse.debug.ui.memory.MemoryRenderingElement;
29 import org.eclipse.jface.viewers.ICellModifier;
30 import org.eclipse.swt.widgets.TableItem;
31
32 /**
33  * @since 3.1
34  *
35  */

36 // TODO: if we want "true" flexible hierarchy, also need to allow clients
37
// to plug cell modifier in case the element is not MemorySegment
38
public class AsyncTableRenderingCellModifier implements ICellModifier {
39
40     private AbstractAsyncTableRendering fRendering;
41     private boolean fMBSupportsValueModification = false;
42     
43     private ICellModifier fCustomModifier;
44
45     public AsyncTableRenderingCellModifier(AbstractAsyncTableRendering rendering, ICellModifier customModifier) {
46         fRendering = rendering;
47         fCustomModifier = customModifier;
48         
49         Job job = new Job("AsyncTableRenderingCellModifier"){ //$NON-NLS-1$
50

51             protected IStatus run(IProgressMonitor monitor) {
52                 fMBSupportsValueModification = fRendering.getMemoryBlock().supportsValueModification();
53                 return Status.OK_STATUS;
54             }};
55         job.setSystem(true);
56         job.schedule();
57     }
58
59     /*
60      * (non-Javadoc)
61      *
62      * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object,
63      * java.lang.String)
64      */

65     public boolean canModify(Object JavaDoc element, String JavaDoc property) {
66         boolean canModify = true;
67         try {
68             if (!(element instanceof MemorySegment))
69                 return false;
70
71             if (!isValueModificationSupported()) {
72                 return false;
73             }
74
75             MemorySegment line = (MemorySegment) element;
76             if (TableRenderingLine.P_ADDRESS.equals(property)) {
77                 return false;
78             }
79             
80             // property is stored as number of addressable unit away from the
81
// line address
82
// to calculate offset to the memory line array, offset =
83
// numberofAddressableUnit * addressableSize
84
int addressableSize = getAddressableSize();
85
86             int offset = Integer.valueOf(property, 16).intValue() * addressableSize;
87
88             MemoryByte[] bytes = line.getBytes(offset, fRendering.getBytesPerColumn());
89
90             if (fCustomModifier != null)
91             {
92                 BigInteger JavaDoc address = line.getAddress().add(BigInteger.valueOf(offset));
93                 MemoryRenderingElement mElement = new MemoryRenderingElement(fRendering, address, bytes);
94                 return fCustomModifier.canModify(mElement, null);
95             }
96
97             for (int i = 0; i < bytes.length; i++) {
98                 if (!bytes[i].isWritable()) {
99                     canModify = false;
100                 }
101             }
102             return canModify;
103         } catch (NumberFormatException JavaDoc e) {
104             canModify = false;
105             return canModify;
106         }
107     }
108
109     /**
110      * @return
111      */

112     private int getAddressableSize() {
113         int addressableSize = fRendering.getAddressableSize();
114         if (addressableSize < 1)
115             addressableSize = 1;
116         return addressableSize;
117     }
118
119     /*
120      * (non-Javadoc)
121      *
122      * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object,
123      * java.lang.String)
124      */

125     public Object JavaDoc getValue(Object JavaDoc element, String JavaDoc property) {
126         
127         // give back the value of the column
128

129         if (!(element instanceof MemorySegment))
130             return null;
131
132         MemorySegment line = (MemorySegment) element;
133         try {
134             if (TableRenderingLine.P_ADDRESS.equals(property))
135                 return line.getAddress();
136
137             int offsetToLineBuffer = Integer.valueOf(property, 16).intValue() * getAddressableSize();
138             MemoryByte[] memory = line.getBytes(offsetToLineBuffer, fRendering.getBytesPerColumn());
139
140             int offsetFromLineAddress = Integer.valueOf(property, 16).intValue();
141             BigInteger JavaDoc address = line.getAddress().add(BigInteger.valueOf(offsetFromLineAddress));
142             
143             if (fCustomModifier != null)
144             {
145                 MemoryRenderingElement mElement = new MemoryRenderingElement(fRendering, address, memory);
146                 return fCustomModifier.getValue(mElement, null);
147             }
148
149             // ask the rendering for a string representation of the bytes
150
return fRendering.getString(fRendering.getRenderingId(), address, memory);
151
152         } catch (NumberFormatException JavaDoc e) {
153             return "00"; //$NON-NLS-1$
154
}
155     }
156
157     /*
158      * (non-Javadoc)
159      *
160      * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object,
161      * java.lang.String, java.lang.Object)
162      */

163     public void modify(Object JavaDoc element, final String JavaDoc property, final Object JavaDoc value) {
164         
165         MemorySegment segment = null;
166         if (element instanceof TableItem) {
167             Object JavaDoc data = ((TableItem)element).getData();
168             if (data != null && data instanceof MemorySegment)
169                 segment = (MemorySegment)data;
170             
171         } else if (element instanceof MemorySegment){
172             segment = (MemorySegment) element;
173         }
174         
175         if (segment == null)
176             return;
177         
178         final MemorySegment line = segment;
179         
180         Job job = new Job("Set Values"){ //$NON-NLS-1$
181

182             protected IStatus run(IProgressMonitor monitor) {
183                 try {
184                     // calculate offset to update
185
final IMemoryBlock memoryBlk = fRendering.getMemoryBlock();
186
187                     // number of addressable units from the line's start address
188
int offsetFromLineAddress = Integer.valueOf(property, 16).intValue();
189
190                     // this offset is number of addressable unit from memory block's base address
191
final BigInteger JavaDoc offsetFromMBBase = getOffset(memoryBlk, line.getAddress(), offsetFromLineAddress);
192
193                     // property is number of addressable unit from line address
194
// to calculate proper offset in the memoryViewLine's array
195
// offset = numberOfAddressableUnit * addressableSize
196
int offsetToLineBuffer = Integer.valueOf(property, 16).intValue() * getAddressableSize();
197
198                     MemoryByte[] oldArray = line.getBytes(offsetToLineBuffer, fRendering.getBytesPerColumn());
199
200                     // address is line address + addressable unit into the line
201
BigInteger JavaDoc address = line.getAddress();
202                     address = address.add(BigInteger.valueOf(offsetFromLineAddress));
203
204                     if (fCustomModifier != null) {
205                         MemoryRenderingElement mElement = new MemoryRenderingElement(fRendering, address, oldArray);
206                         fCustomModifier.modify(mElement, null, value);
207                         return Status.OK_STATUS;
208                     }
209                     
210                     if (!(value instanceof String JavaDoc))
211                     {
212                         DebugUIPlugin.logErrorMessage("Cell modifier cannot handle non-string values."); //$NON-NLS-1$
213
return Status.OK_STATUS;
214                     }
215                     
216                   byte[] bytes = null;
217                   String JavaDoc oldValue = (String JavaDoc) getValue(line, property);
218                   if (!oldValue.equals(value)) {
219                         bytes = fRendering.getBytes(fRendering.getRenderingId(), address, oldArray, (String JavaDoc) value);
220
221                         if (bytes == null)
222                             return Status.OK_STATUS;
223
224                         if (bytes.length == 0)
225                              return Status.OK_STATUS;
226
227                         if (bytes.length <= oldArray.length) {
228                             boolean changed = false;
229                             // check that the bytes returned has actually changed
230
for (int i = 0; i < bytes.length; i++) {
231                                 if (bytes[i] != oldArray[i].getValue()) {
232                                     changed = true;
233                                     break;
234                                 }
235                             }
236                             if (!changed)
237                                  return Status.OK_STATUS;
238                         }
239                     } else {
240                         // return if value has not changed
241
return Status.OK_STATUS;
242                     }
243                     
244                     final byte[] newByteValues = bytes;
245                     
246                     if (memoryBlk instanceof IMemoryBlockExtension)
247                         ((IMemoryBlockExtension) memoryBlk).setValue(offsetFromMBBase, newByteValues);
248                     else
249                         memoryBlk.setValue(offsetFromMBBase.longValue(), newByteValues);
250                 } catch (DebugException e) {
251                     MemoryViewUtil.openError(DebugUIMessages.MemoryViewCellModifier_failure_title, DebugUIMessages.MemoryViewCellModifier_failed, e);
252                 } catch (NumberFormatException JavaDoc e) {
253                     MemoryViewUtil.openError(DebugUIMessages.MemoryViewCellModifier_failure_title, DebugUIMessages.MemoryViewCellModifier_failed + "\n" + DebugUIMessages.MemoryViewCellModifier_data_is_invalid, null); //$NON-NLS-1$
254
}
255                 return Status.OK_STATUS;
256             }};
257
258        job.setSystem(true);
259        job.schedule();
260     }
261
262     private BigInteger JavaDoc getOffset(IMemoryBlock memory, BigInteger JavaDoc lineAddress, int lineOffset) throws DebugException {
263
264         BigInteger JavaDoc memoryAddr;
265
266         if (memory instanceof IMemoryBlockExtension) {
267             memoryAddr = ((IMemoryBlockExtension) memory).getBigBaseAddress();
268         } else {
269             memoryAddr = BigInteger.valueOf(memory.getStartAddress());
270         }
271
272         if (memoryAddr == null)
273             memoryAddr = new BigInteger JavaDoc("0"); //$NON-NLS-1$
274

275         return lineAddress.subtract(memoryAddr).add(BigInteger.valueOf(lineOffset));
276     }
277     
278     private boolean isValueModificationSupported()
279     {
280         return fMBSupportsValueModification;
281     }
282
283 }
284
Popular Tags