KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2004, 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 package org.eclipse.debug.internal.ui.views.memory;
12
13 import java.math.BigInteger JavaDoc;
14 import java.util.Enumeration JavaDoc;
15 import java.util.Hashtable JavaDoc;
16
17 import org.eclipse.core.runtime.SafeRunner;
18 import org.eclipse.debug.core.IMemoryBlockListener;
19 import org.eclipse.debug.core.model.IMemoryBlock;
20 import org.eclipse.debug.ui.memory.IMemoryRendering;
21 import org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService;
22 import org.eclipse.jface.util.IPropertyChangeListener;
23 import org.eclipse.jface.util.PropertyChangeEvent;
24 import org.eclipse.swt.widgets.Display;
25
26 /**
27  * Synchronization service for the memory view.
28  * @since 3.1
29  */

30 public class MemoryViewSynchronizationService implements
31         IMemoryRenderingSynchronizationService, IMemoryBlockListener, IPropertyChangeListener {
32
33     private static final int ENABLED = 0;
34     private static final int ENABLING = 1;
35     private static final int DISABLED = 2;
36     
37     private Hashtable JavaDoc fSynchronizeInfo;
38     private int fEnableState = ENABLED;
39     private Hashtable JavaDoc fPropertyListeners;
40     
41     private IMemoryRendering fLastChangedRendering;
42     private IMemoryRendering fSyncServiceProvider;
43
44     private static final boolean DEBUG_SYNC_SERVICE = false;
45     
46     public MemoryViewSynchronizationService()
47     {
48         fSynchronizeInfo = new Hashtable JavaDoc();
49         fPropertyListeners = new Hashtable JavaDoc();
50         MemoryViewUtil.getMemoryBlockManager().addListener(this);
51     }
52
53     /**
54      * Wrapper for ISynchronizedMemoryBlockView
55      * Holds a list of property filters for the view.
56      */

57     class PropertyListener
58     {
59         IPropertyChangeListener fListener;
60         String JavaDoc[] fFilters;
61         
62         public PropertyListener(IPropertyChangeListener listener, String JavaDoc[] properties)
63         {
64             fListener = listener;
65             
66             if(properties != null)
67             {
68                 fFilters = properties;
69             }
70         }
71
72         /**
73          * If the property matches one of the filters, the property
74          * is valid and the view should be notified about its change.
75          * @param property
76          * @return if the property is specified in the filter
77          */

78         public boolean isValidProperty(String JavaDoc property){
79             if (fFilters == null)
80                 return true;
81             for (int i=0; i<fFilters.length; i++)
82             {
83                 if (fFilters[i].equals(property))
84                 {
85                     return true;
86                 }
87             }
88             return false;
89         }
90
91         /**
92          * Set property filters, indicating what property change events
93          * the listener is interested in.
94          * @param filters
95          */

96         public void setPropertyFilters(String JavaDoc[] filters){
97             fFilters = filters;
98         }
99
100         /**
101          * @return Returns the fListener.
102          */

103         public IPropertyChangeListener getListener() {
104             return fListener;
105         }
106     }
107     
108     /* (non-Javadoc)
109      * @see org.eclipse.debug.ui.IMemoryBlockViewSynchronizer#getSynchronizedProperty(org.eclipse.debug.ui.ISynchronizedMemoryBlockView, java.lang.String)
110      */

111     public Object JavaDoc getSynchronizedProperty(IMemoryBlock memoryBlock, String JavaDoc propertyId)
112     {
113         SynchronizeInfo info = (SynchronizeInfo)fSynchronizeInfo.get(memoryBlock);
114         
115         if (info != null)
116         {
117             Object JavaDoc value = info.getProperty(propertyId);
118             return value;
119         }
120         
121         return null;
122     }
123
124     /* (non-Javadoc)
125      * @see org.eclipse.debug.ui.IMemoryBlockListener#MemoryBlockAdded(org.eclipse.debug.core.model.IMemoryBlock)
126      */

127     public void memoryBlocksAdded(IMemoryBlock[] memoryBlocks) {
128         // do nothing when a memory block is added
129
// create a synchronize info object when there is a fView
130
// tab registered to be synchronized.
131

132         
133     }
134
135     /* (non-Javadoc)
136      * @see org.eclipse.debug.ui.IMemoryBlockListener#MemoryBlockRemoved(org.eclipse.debug.core.model.IMemoryBlock)
137      */

138     public void memoryBlocksRemoved(IMemoryBlock[] memoryBlocks) {
139         
140         // Sync info can be null if the service is already shut down
141
if (fSynchronizeInfo == null)
142             return;
143         
144         for (int i=0; i<memoryBlocks.length; i++)
145         {
146             IMemoryBlock memory = memoryBlocks[i];
147             
148             if (fLastChangedRendering != null && fLastChangedRendering.getMemoryBlock() == memory)
149                 fLastChangedRendering = null;
150             
151             if (fSyncServiceProvider != null && fSyncServiceProvider.getMemoryBlock() == memory)
152                 fSyncServiceProvider = null;
153             
154             // delete the info object and remove it from fSynchronizeInfo
155
// when the memory block is deleted
156
SynchronizeInfo info = (SynchronizeInfo)fSynchronizeInfo.get(memory);
157             
158             if (info != null)
159             {
160                 info.delete();
161                 fSynchronizeInfo.remove(memory);
162             }
163         }
164     }
165     
166     /**
167      * Clean up when the plugin is shutdown
168      */

169     public void shutdown()
170     {
171         if (fSynchronizeInfo != null)
172         {
173             Enumeration JavaDoc enumeration = fSynchronizeInfo.elements();
174             
175             // clean up all synchronize info objects
176
while (enumeration.hasMoreElements()){
177                 SynchronizeInfo info = (SynchronizeInfo)enumeration.nextElement();
178                 info.delete();
179             }
180             
181             fSynchronizeInfo.clear();
182             fSynchronizeInfo = null;
183         }
184         MemoryViewUtil.getMemoryBlockManager().removeListener(this);
185     }
186     
187     
188     /* (non-Javadoc)
189      * @see org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener, java.lang.String[])
190      */

191     public void addPropertyChangeListener(IPropertyChangeListener listener, String JavaDoc[] properties) {
192         
193         PropertyListener propertylistener = new PropertyListener(listener, properties);
194         
195         if (!fPropertyListeners.contains(propertylistener))
196         {
197             fPropertyListeners.put(listener, propertylistener);
198         }
199
200     }
201
202     /* (non-Javadoc)
203      * @see org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
204      */

205     public void removePropertyChangeListener(IPropertyChangeListener listener) {
206         if (fPropertyListeners.containsKey(listener))
207         {
208             fPropertyListeners.remove(listener);
209         }
210     }
211     
212     /**
213      * Fire property change events
214      * @param propertyId
215      */

216     public void firePropertyChanged(final PropertyChangeEvent evt)
217     {
218         // do not fire property changed event if the synchronization
219
// service is disabled
220
if (fEnableState == DISABLED)
221             return;
222         
223         // Make sure the synchronizer does not swallow any events
224
// Values of the properties are updated in the syncrhonizer immediately.
225
// Change events are queued up on the UI Thread.
226
Display.getDefault().syncExec(new Runnable JavaDoc()
227         {
228             public void run()
229             {
230                 if (fSynchronizeInfo == null)
231                     return;
232                 
233                 IMemoryRendering rendering = (IMemoryRendering)evt.getSource();
234                 String JavaDoc propertyId = evt.getProperty();
235                 
236                 SynchronizeInfo info = (SynchronizeInfo)fSynchronizeInfo.get(rendering.getMemoryBlock());
237                 if (info != null)
238                 {
239                     Object JavaDoc value = info.getProperty(propertyId);
240                     if (value != null)
241                     {
242                         Enumeration JavaDoc enumeration = fPropertyListeners.elements();
243                         
244                         while(enumeration.hasMoreElements())
245                         {
246                             PropertyListener listener = (PropertyListener)enumeration.nextElement();
247                             
248                             IPropertyChangeListener origListener = listener.getListener();
249                             
250                             // if it's a valid property - valid means that it's listed in the property filters
251
if (listener.isValidProperty(propertyId)){
252                                 PropertyChangeNotifier notifier = new PropertyChangeNotifier(origListener, evt);
253                                 SafeRunner.run(notifier);
254                             }
255                         }
256                     }
257                 }
258             }
259         });
260     }
261     
262     /* (non-Javadoc)
263      * @see org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService#getProperty(org.eclipse.debug.core.model.IMemoryBlock, java.lang.String)
264      */

265     public Object JavaDoc getProperty(IMemoryBlock block, String JavaDoc property) {
266         
267         // When the synchronization service is disabled
268
// return null for all queries to properties
269
// This is to ensure that renderings are not synchronized
270
// to new synchronization properties when the sync service is
271
// disabled.
272
if (!isEnabled())
273             return null;
274         
275         SynchronizeInfo info = (SynchronizeInfo)fSynchronizeInfo.get(block);
276         
277         if (info != null)
278             return info.getProperty(property);
279         
280         return null;
281     }
282     
283
284     /* (non-Javadoc)
285      * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
286      */

287     public void propertyChange(PropertyChangeEvent event) {
288         if (event == null || !(event.getSource() instanceof IMemoryRendering))
289         {
290             return;
291         }
292         
293         // Do not handle any property changed event as the
294
// sync service is being enabled.
295
// Otheriwse, current sync info provider may overwrite
296
// sync info unexpectedly. We want to sync with the rendering
297
// that is last changed.
298
if (fEnableState == ENABLING)
299             return;
300         
301         IMemoryRendering rendering = ((IMemoryRendering)event.getSource());
302         IMemoryBlock memoryBlock = rendering.getMemoryBlock();
303         String JavaDoc propertyId = event.getProperty();
304         Object JavaDoc value = event.getNewValue();
305         
306         if (DEBUG_SYNC_SERVICE)
307         {
308             System.out.println("SYNC SERVICE RECEIVED CHANGED EVENT:"); //$NON-NLS-1$
309
System.out.println("Source: " + rendering); //$NON-NLS-1$
310
System.out.println("Property: " + propertyId); //$NON-NLS-1$
311
System.out.println("Value: " + value); //$NON-NLS-1$
312

313             if (value instanceof BigInteger JavaDoc)
314             {
315                 System.out.println("Value in hex: " + ((BigInteger JavaDoc)value).toString(16)); //$NON-NLS-1$
316
}
317         }
318         
319         if (memoryBlock == null)
320             return;
321         
322         if (propertyId == null)
323             return;
324         
325         // find the synchronize info object for the memory block
326
SynchronizeInfo info = (SynchronizeInfo)fSynchronizeInfo.get(memoryBlock);
327         
328         // if info is not available, need to create one to hold the property
329
if (info == null)
330         {
331             info = new SynchronizeInfo(memoryBlock);
332             fSynchronizeInfo.put(memoryBlock, info);
333         }
334         
335         // get the value of the property
336
Object JavaDoc oldValue = info.getProperty(propertyId);
337         
338         if (oldValue == null)
339         {
340             // if the value has never been added to the info object
341
// set the property and fire a change event
342
info.setProperty(propertyId, value);
343             fLastChangedRendering = rendering;
344             firePropertyChanged(event);
345             return;
346         }
347         else if (!oldValue.equals(value))
348         {
349             // if the value has changed
350
// set the property and fire a change event
351
info.setProperty(propertyId, value);
352             fLastChangedRendering = rendering;
353             firePropertyChanged(event);
354         }
355     }
356     
357     public void setEnabled(boolean enabled)
358     {
359         if (enabled && fEnableState == ENABLED)
360             return;
361         
362         if (!enabled && fEnableState == DISABLED)
363             return;
364         
365         try
366         {
367             if (enabled)
368             {
369                 fEnableState = ENABLING;
370                 // get sync info from the sync service provider
371
if (fLastChangedRendering != null)
372                 {
373                     IMemoryBlock memBlock = fLastChangedRendering.getMemoryBlock();
374                     SynchronizeInfo info = (SynchronizeInfo)fSynchronizeInfo.get(memBlock);
375                     String JavaDoc[] ids = info.getPropertyIds();
376                     
377                     // stop handling property changed event while the
378
// synchronization service is being enabled
379
// this is to get around problem when the last changed
380
// rendering is not currently the sync info provider
381

382                     for (int i=0; i<ids.length; i++)
383                     {
384                         PropertyChangeEvent evt = new PropertyChangeEvent(fLastChangedRendering, ids[i], null, info.getProperty(ids[i]));
385                         firePropertyChanged(evt);
386                     }
387                 }
388             }
389         }
390         finally
391         {
392             if (enabled)
393                 fEnableState = ENABLED;
394             else
395                 fEnableState = DISABLED;
396         }
397     }
398     
399     public boolean isEnabled()
400     {
401         return fEnableState == ENABLED;
402     }
403     
404
405     /* (non-Javadoc)
406      * @see org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService#setSynchronizationProvider(org.eclipse.debug.ui.memory.IMemoryRendering)
407      */

408     public void setSynchronizationProvider(IMemoryRendering rendering) {
409         
410         if (DEBUG_SYNC_SERVICE)
411             System.out.println("SYNCHRONIZATION PROVIDER: " + rendering); //$NON-NLS-1$
412

413         if (fSyncServiceProvider != null)
414             fSyncServiceProvider.removePropertyChangeListener(this);
415         
416         if (rendering != null)
417             rendering.addPropertyChangeListener(this);
418         
419         fSyncServiceProvider = rendering;
420     }
421     
422
423     /* (non-Javadoc)
424      * @see org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService#getSynchronizationProvider()
425      */

426     public IMemoryRendering getSynchronizationProvider() {
427         return fSyncServiceProvider;
428     }
429 }
430
Popular Tags