KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2006 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 import java.util.ArrayList JavaDoc;
16 import java.util.Enumeration JavaDoc;
17 import java.util.Hashtable JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Vector JavaDoc;
20
21 import org.eclipse.core.runtime.Assert;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.core.runtime.IStatus;
24 import org.eclipse.core.runtime.Status;
25 import org.eclipse.core.runtime.jobs.Job;
26 import org.eclipse.debug.core.model.IMemoryBlock;
27 import org.eclipse.debug.core.model.IMemoryBlockExtension;
28 import org.eclipse.debug.core.model.MemoryByte;
29 import org.eclipse.debug.internal.ui.memory.provisional.AbstractAsyncTableRendering;
30 import org.eclipse.debug.internal.ui.memory.provisional.MemoryViewPresentationContext;
31 import org.eclipse.debug.internal.ui.viewers.AsynchronousTableViewer;
32 import org.eclipse.debug.internal.ui.viewers.ModelNode;
33 import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
34 import org.eclipse.debug.ui.memory.IMemoryRendering;
35
36
37 public class TableRenderingModel extends AbstractVirtualContentTableModel
38         implements IContentChangeComputer {
39
40
41     private Hashtable JavaDoc fCache;
42     private Vector JavaDoc fOrderedCache; // needed to re-organize cache
43

44     private boolean fMBSupportsChangeManagement;
45     private IMemoryBlock fMemoryBlock;
46
47     class SupportsChangeMgmtJob extends Job {
48         
49         SupportsChangeMgmtJob()
50         {
51             super("Support Change Management"); //$NON-NLS-1$
52
setSystem(true);
53         }
54
55         protected IStatus run(IProgressMonitor monitor) {
56             IMemoryBlock mb = getMemoryBlock();
57             if (mb instanceof IMemoryBlockExtension)
58             {
59                 IMemoryBlockExtension mbExt = (IMemoryBlockExtension)mb;
60                 fMBSupportsChangeManagement = mbExt.supportsChangeManagement();
61             }
62             return Status.OK_STATUS;
63         }
64         
65     }
66     
67     
68     public TableRenderingModel(AsynchronousTableViewer viewer) {
69         super(viewer);
70         fCache = new Hashtable JavaDoc();
71         fOrderedCache = new Vector JavaDoc();
72     }
73     
74     public int indexOfKey(Object JavaDoc key)
75     {
76         if (key instanceof BigInteger JavaDoc)
77         {
78             BigInteger JavaDoc address = (BigInteger JavaDoc)key;
79             Object JavaDoc items[] = getElements();
80             
81             for (int i=0; i<items.length; i++){
82                 if (items[i] != null && items[i] instanceof MemorySegment)
83                 {
84                     MemorySegment line = (MemorySegment)items[i];
85                     if (line.containsAddress(address))
86                         return i;
87                 }
88             }
89         }
90         
91         return -1;
92     }
93     
94     public int columnOf(Object JavaDoc element, Object JavaDoc key)
95     {
96         if (element instanceof MemorySegment && key instanceof BigInteger JavaDoc)
97         {
98             BigInteger JavaDoc address = (BigInteger JavaDoc)key;
99             MemorySegment line = (MemorySegment)element;
100             if (line.containsAddress(address))
101             {
102                 if (getAddressableUnitsPerColumn() > 0)
103                 {
104                     BigInteger JavaDoc offset = address.subtract(line.getAddress());
105                     
106                     // locate column
107
int colAddressableUnit = getAddressableUnitsPerColumn();
108                     int col = ((offset.intValue()/colAddressableUnit)+1);
109                     
110                     if (col == 0)
111                         col = 1;
112                     
113                     return col;
114                 }
115             }
116         }
117         
118         return -1;
119     }
120     
121     public Object JavaDoc getKey(int idx)
122     {
123         Object JavaDoc elmt = getElement(idx);
124         if (elmt instanceof MemorySegment)
125         {
126             return ((MemorySegment)elmt).getAddress();
127         }
128     
129         return null;
130     }
131
132     public Object JavaDoc getKey(Object JavaDoc element) {
133         int idx = indexOfElement(element);
134         if (idx >= 0)
135         {
136             return getKey(idx);
137         }
138         return null;
139     }
140     
141     public Object JavaDoc getKey(int idx, int col) {
142         Object JavaDoc element = getElement(idx);
143         if (element != null && element instanceof MemorySegment)
144         {
145             MemorySegment segment = (MemorySegment)element;
146             BigInteger JavaDoc rowAddress = segment.getAddress();
147             
148             int offset;
149             if (col > 0)
150             {
151                 // get address offset
152
int addressableUnit = getAddressableUnitsPerColumn();
153                 offset = (col-1) * addressableUnit;
154             }
155             else
156             {
157                 offset = 0;
158             }
159             return rowAddress.add(BigInteger.valueOf(offset));
160         }
161         return null;
162     }
163     
164     private int getAddressableUnitsPerColumn()
165     {
166         AsynchronousTableViewer viewer = getTableViewer();
167         if (viewer.getPresentationContext() instanceof MemoryViewPresentationContext)
168         {
169             MemoryViewPresentationContext context = (MemoryViewPresentationContext)viewer.getPresentationContext();
170             if (getTableRendering(context)!= null)
171             {
172                 return getTableRendering(context).getAddressableUnitPerColumn();
173             }
174         }
175         return -1;
176     }
177
178     public void cache(Object JavaDoc[] elements) {
179         for (int i=0; i<elements.length; i++)
180         {
181             Object JavaDoc obj = elements[i];
182             if (obj instanceof MemorySegment)
183             {
184                 cache(((MemorySegment)obj).getAddress(), obj);
185             }
186         }
187         
188     }
189     
190     private void cache(Object JavaDoc key, Object JavaDoc element)
191     {
192         fCache.put(key, element);
193         fOrderedCache.add(element);
194     }
195
196     public Object JavaDoc[] compare(Object JavaDoc[] newElements) {
197         
198         if (fCache.isEmpty())
199             return newElements;
200         
201         for (int j=0; j<newElements.length; j++)
202         {
203             Object JavaDoc obj = newElements[j];
204             if (obj instanceof MemorySegment)
205             {
206                 MemorySegment newSegment = (MemorySegment)obj;
207                 MemorySegment oldSegment = (MemorySegment)fCache.get(newSegment.getAddress());
208
209                 if (oldSegment != null)
210                 {
211                     if (oldSegment.getNumAddressableUnits() == newSegment.getNumAddressableUnits())
212                     {
213                         MemoryByte[] newBytes = newSegment.getBytes();
214                         MemoryByte[] oldBytes = oldSegment.getBytes();
215                         
216                         for (int i=0; i<newBytes.length; i++)
217                         {
218                             newBytes[i].setHistoryKnown(true);
219                             
220                             if (newBytes[i].isReadable() != oldBytes[i].isReadable())
221                             {
222                                 newBytes[i].setChanged(true);
223                                 continue;
224                             }
225
226                             if (newBytes[i].isReadable() && oldBytes[i].isReadable() &&
227                                 (newBytes[i].getValue() != oldBytes[i].getValue()))
228                                 newBytes[i].setChanged(true);
229                         }
230                     }
231                 }
232             }
233         }
234         return newElements;
235     }
236     
237     public void clearCache()
238     {
239         fCache.clear();
240         fOrderedCache.clear();
241     }
242
243     public boolean isEmpty() {
244         return fCache.isEmpty();
245     }
246
247     public void handleViewerChanged() {
248         // viewer has changed, content manager needs to re-organize the cache
249
rebuildCache();
250         rebuildContent();
251     }
252     
253     private void rebuildCache()
254     {
255         if (isEmpty())
256             return;
257         
258         MemoryViewPresentationContext context = (MemoryViewPresentationContext)getTableViewer().getPresentationContext();
259         AbstractAsyncTableRendering rendering = getTableRendering(context);
260         
261         if (rendering == null)
262             return;
263         
264         ArrayList JavaDoc segments = new ArrayList JavaDoc();
265         Enumeration JavaDoc enumeration = fOrderedCache.elements();
266         
267         BigInteger JavaDoc address = ((MemorySegment)fOrderedCache.get(0)).getAddress();
268         while (enumeration.hasMoreElements())
269         {
270             Object JavaDoc element = enumeration.nextElement();
271             if (element instanceof MemorySegment)
272             {
273                 
274                 segments.add(element);
275             }
276         }
277         
278         MemoryByte[] bytes = convertSegmentsToBytes((MemorySegment[])segments.toArray(new MemorySegment[0]));
279         
280         int bytesPerLine = rendering.getBytesPerLine();
281         int numAddressableUnitPerLine = rendering.getAddressableUnitPerLine();
282         
283         int addressableSize = rendering.getAddressableSize();
284         
285         clearCache();
286         
287         TableRenderingContentDescriptor descriptor = (TableRenderingContentDescriptor)rendering.getAdapter(TableRenderingContentDescriptor.class);
288         boolean alignAddress = true;
289         if (descriptor != null && !descriptor.isAlignAddressToBoundary())
290         {
291             alignAddress = descriptor.isAlignAddressToBoundary();
292         }
293         
294         MemorySegment[] newSegments = convertMemoryBytesToSegments(address, bytes, bytesPerLine, numAddressableUnitPerLine, addressableSize, alignAddress);
295         for (int i=0; i<newSegments.length; i++)
296         {
297             cache(newSegments[i].getAddress(), newSegments[i]);
298         }
299     }
300     
301     private void rebuildContent()
302     {
303         MemoryViewPresentationContext context = (MemoryViewPresentationContext)getTableViewer().getPresentationContext();
304         AbstractAsyncTableRendering rendering = getTableRendering(context);
305         
306         if (rendering == null)
307             return;
308         
309         ArrayList JavaDoc segments = new ArrayList JavaDoc();
310         Object JavaDoc[] elements = getElements();
311         for (int i=0; i<elements.length; i++)
312         {
313             Object JavaDoc element = elements[i];
314             if (element instanceof MemorySegment)
315             {
316                 segments.add(element);
317             }
318         }
319         
320         MemoryByte[] bytes = convertSegmentsToBytes((MemorySegment[])segments.toArray(new MemorySegment[segments.size()]));
321         
322         int bytesPerLine = rendering.getBytesPerLine();
323         int numAddressableUnitPerLine = rendering.getAddressableUnitPerLine();
324         BigInteger JavaDoc address = (BigInteger JavaDoc)getKey(0);
325
326         int addressableSize = rendering.getAddressableSize();
327         
328         TableRenderingContentDescriptor descriptor = (TableRenderingContentDescriptor)rendering.getAdapter(TableRenderingContentDescriptor.class);
329         boolean alignAddress = true;
330         if (descriptor != null && !descriptor.isAlignAddressToBoundary())
331         {
332             alignAddress = descriptor.isAlignAddressToBoundary();
333         }
334         
335         MemorySegment[] newSegments = convertMemoryBytesToSegments(address, bytes, bytesPerLine, numAddressableUnitPerLine, addressableSize, alignAddress);
336         remove(getElements());
337         add(newSegments);
338     }
339
340     
341     private MemoryByte[] convertSegmentsToBytes(MemorySegment[] segments)
342     {
343         ArrayList JavaDoc toReturn = new ArrayList JavaDoc();
344         for (int i=0; i<segments.length; i++)
345         {
346             MemoryByte[] temp = segments[i].getBytes();
347             for (int j=0; j<temp.length; j++)
348             {
349                 toReturn.add(temp[j]);
350             }
351         }
352         return (MemoryByte[])toReturn.toArray(new MemoryByte[0]);
353     }
354     
355     private MemorySegment[] convertMemoryBytesToSegments(BigInteger JavaDoc address, MemoryByte[] bytes, int bytesPerLine, int numAddressableUnitPerLine, int addressableSize, boolean alignAddress) {
356         
357         Assert.isTrue(bytesPerLine > 0);
358         Assert.isTrue(numAddressableUnitPerLine > 0);
359         
360         ArrayList JavaDoc segments = new ArrayList JavaDoc();
361         MemoryByte[] temp = bytes;
362         
363         if (alignAddress)
364         {
365             BigInteger JavaDoc alignedAddress = MemoryViewUtil.alignToBoundary(address, numAddressableUnitPerLine);
366             
367             // also check that the address is properly aligned and prepend bytes if need to
368
if (!address.subtract(alignedAddress).equals(BigInteger.ZERO))
369             {
370                 BigInteger JavaDoc unitsToSetBack = address.subtract(alignedAddress);
371                 BigInteger JavaDoc tempAddress = address.subtract(unitsToSetBack);
372                 // only do this if the resulted address >= 0
373
// do not want to have negative addresses
374
if (tempAddress.compareTo(BigInteger.ZERO) >= 0)
375                 {
376                     address = alignedAddress;
377                     int numBytesNeeded = unitsToSetBack.intValue() * addressableSize;
378                     temp = new MemoryByte[bytes.length + numBytesNeeded];
379                     
380                     for (int i=0; i<numBytesNeeded; i++)
381                     {
382                         temp[i] = new MemoryByte();
383                         temp[i].setReadable(false);
384                         temp[i].setWritable(false);
385                         temp[i].setEndianessKnown(false);
386                     }
387                     
388                     System.arraycopy(bytes, 0, temp, numBytesNeeded, bytes.length);
389                     bytes = temp;
390                 }
391             }
392         }
393         
394         if (bytes.length % bytesPerLine != 0)
395         {
396             int numBytesNeeded = bytesPerLine - (bytes.length % bytesPerLine);
397             temp = new MemoryByte[bytes.length + numBytesNeeded];
398             System.arraycopy(bytes, 0, temp, 0, bytes.length);
399             
400             for (int i=bytes.length; i<temp.length; i++)
401             {
402                 temp[i] = new MemoryByte();
403                 temp[i].setReadable(false);
404                 temp[i].setWritable(false);
405                 temp[i].setEndianessKnown(false);
406             }
407             bytes = temp;
408         }
409         
410         int idx = 0;
411         while (idx < bytes.length && (idx + bytesPerLine)<= bytes.length)
412         {
413             MemoryByte[] newBytes = new MemoryByte[bytesPerLine];
414             System.arraycopy(bytes, idx, newBytes, 0, bytesPerLine);
415             
416             MemorySegment segment = new MemorySegment(address, newBytes, numAddressableUnitPerLine);
417             segments.add(segment);
418             
419             address = address.add(BigInteger.valueOf(numAddressableUnitPerLine));
420             idx += bytesPerLine;
421         }
422         
423         return (MemorySegment[])segments.toArray(new MemorySegment[segments.size()]);
424     }
425     
426     private AsynchronousTableViewer getTableViewer()
427     {
428         return (AsynchronousTableViewer)getViewer();
429     }
430
431     protected void setChildren(ModelNode parentNode, List JavaDoc kids) {
432         
433         if (computeChanges())
434         {
435             Object JavaDoc[] newContent = compare(kids.toArray());
436             ArrayList JavaDoc newList = new ArrayList JavaDoc();
437             for (int i=0; i<newContent.length; i++)
438             {
439                 newList.add(newContent[i]);
440             }
441             super.setChildren(parentNode, newList);
442         }
443         else
444             super.setChildren(parentNode, kids);
445     }
446     
447     private boolean computeChanges()
448     {
449         if (isEmpty())
450             return false;
451         
452         if (fMBSupportsChangeManagement)
453         {
454             return false;
455         }
456         
457         return true;
458     }
459     
460     private IMemoryBlock getMemoryBlock()
461     {
462         return fMemoryBlock;
463     }
464     
465
466     public void init(Object JavaDoc root) {
467         if (root instanceof IMemoryBlock)
468         {
469             fMemoryBlock = (IMemoryBlock)root;
470             new SupportsChangeMgmtJob().schedule();
471         }
472         super.init(root);
473     }
474     
475     private AbstractAsyncTableRendering getTableRendering(MemoryViewPresentationContext context)
476     {
477         IMemoryRendering memRendering = context.getRendering();
478         if (memRendering != null && memRendering instanceof AbstractAsyncTableRendering)
479         {
480             return (AbstractAsyncTableRendering)memRendering;
481         }
482         return null;
483     }
484 }
485
Popular Tags