KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > core > MemoryBlockManager


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
12 package org.eclipse.debug.internal.core;
13
14 import java.util.ArrayList JavaDoc;
15
16 import org.eclipse.core.runtime.ISafeRunnable;
17 import org.eclipse.core.runtime.SafeRunner;
18 import org.eclipse.debug.core.DebugEvent;
19 import org.eclipse.debug.core.DebugException;
20 import org.eclipse.debug.core.DebugPlugin;
21 import org.eclipse.debug.core.IDebugEventSetListener;
22 import org.eclipse.debug.core.IMemoryBlockListener;
23 import org.eclipse.debug.core.IMemoryBlockManager;
24 import org.eclipse.debug.core.model.IDebugTarget;
25 import org.eclipse.debug.core.model.IMemoryBlock;
26 import org.eclipse.debug.core.model.IMemoryBlockExtension;
27 import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
28
29
30 /**
31  * Implementation of IMemoryBlockManager
32  * The manager is responsible to manage all memory blocks in the workbench.
33  *
34  * @since 3.1
35  *
36  */

37 public class MemoryBlockManager implements IMemoryBlockManager, IDebugEventSetListener {
38     
39     private ArrayList JavaDoc listeners = new ArrayList JavaDoc(); // list of all IMemoryBlockListener
40
private ArrayList JavaDoc memoryBlocks = new ArrayList JavaDoc(); // list of all memory blocks
41

42     private static final int ADDED = 0;
43     private static final int REMOVED = 1;
44     /**
45      * Notifies a memory block listener in a safe runnable to
46      * handle exceptions.
47      */

48     class MemoryBlockNotifier implements ISafeRunnable {
49         
50         private IMemoryBlockListener fListener;
51         private int fType;
52         private IMemoryBlock[] fMemoryBlocks;
53         
54         /**
55          * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
56          */

57         public void handleException(Throwable JavaDoc exception) {
58             DebugPlugin.log(exception);
59         }
60
61         /**
62          * @see org.eclipse.core.runtime.ISafeRunnable#run()
63          */

64         public void run() throws Exception JavaDoc {
65             switch (fType) {
66                 case ADDED:
67                     fListener.memoryBlocksAdded(fMemoryBlocks);
68                     break;
69                 case REMOVED:
70                     fListener.memoryBlocksRemoved(fMemoryBlocks);
71                     break;
72             }
73         }
74
75         /**
76          * Notify listeners of added/removed memory block events
77          *
78          * @param memBlocks blocks that have changed
79          * @param update type of change
80          */

81         public void notify(IMemoryBlock[] memBlocks, int update) {
82             if (listeners != null) {
83                 fType = update;
84                 Object JavaDoc[] copiedListeners= listeners.toArray(new IMemoryBlockListener[listeners.size()]);
85                 for (int i= 0; i < copiedListeners.length; i++) {
86                     fListener = (IMemoryBlockListener)copiedListeners[i];
87                     fMemoryBlocks = memBlocks;
88                     SafeRunner.run(this);
89                 }
90             }
91             fListener = null;
92             fMemoryBlocks = null;
93         }
94     }
95     
96     /**
97      * Returns the <code>MemoryBlockNotifier</code>
98      * @return the <code>MemoryBlockNotifier</code>
99      *
100      * TODO consider using only one of these, and sync where needed,
101      * this way we are not creating a new every single time.
102      */

103     private MemoryBlockNotifier getMemoryBlockNotifier() {
104         return new MemoryBlockNotifier();
105     }
106
107     /* (non-Javadoc)
108      * @see org.eclipse.debug.ui.IMemoryBlockManager#addMemoryBlock(org.eclipse.debug.core.model.IMemoryBlock)
109      */

110     public void addMemoryBlocks(IMemoryBlock[] mem) {
111         if (memoryBlocks == null) {
112             return;
113         }
114         if (mem == null) {
115             DebugPlugin.logMessage("Null argument passed into IMemoryBlockManager.addMemoryBlock", null); //$NON-NLS-1$
116
return;
117         }
118         
119         if(mem.length > 0) {
120             ArrayList JavaDoc newMemoryBlocks = new ArrayList JavaDoc();
121             for (int i=0; i<mem.length; i++) {
122                 // do not allow duplicates
123
if (!memoryBlocks.contains(mem[i])) {
124                     newMemoryBlocks.add(mem[i]);
125                     memoryBlocks.add(mem[i]);
126                     // add listener for the first memory block added
127
if (memoryBlocks.size() == 1) {
128                         DebugPlugin.getDefault().addDebugEventListener(this);
129                     }
130                 }
131             }
132             notifyListeners((IMemoryBlock[])newMemoryBlocks.toArray(new IMemoryBlock[newMemoryBlocks.size()]), ADDED);
133         }
134     }
135
136     /* (non-Javadoc)
137      * @see org.eclipse.debug.ui.IMemoryBlockManager#removeMemoryBlock(org.eclipse.debug.core.model.IMemoryBlock)
138      */

139     public void removeMemoryBlocks(IMemoryBlock[] memBlocks) {
140         if (memoryBlocks == null) {
141             return;
142         }
143         if (memBlocks == null){
144             DebugPlugin.logMessage("Null argument passed into IMemoryBlockManager.removeMemoryBlock", null); //$NON-NLS-1$
145
return;
146         }
147         
148         if(memBlocks.length > 0) {
149             for (int i=0; i<memBlocks.length; i++) {
150                 memoryBlocks.remove(memBlocks[i]);
151                 // remove listener after the last memory block has been removed
152
if (memoryBlocks.size() == 0) {
153                     DebugPlugin.getDefault().removeDebugEventListener(this);
154                 }
155                 if (memBlocks[i] instanceof IMemoryBlockExtension) {
156                     try {
157                         ((IMemoryBlockExtension)memBlocks[i]).dispose();
158                     } catch (DebugException e) {
159                         DebugPlugin.log(e);
160                     }
161                 }
162             }
163             notifyListeners(memBlocks, REMOVED);
164         }
165     }
166
167     /* (non-Javadoc)
168      * @see org.eclipse.debug.ui.IMemoryBlockManager#addListener(org.eclipse.debug.ui.IMemoryBlockListener)
169      */

170     public void addListener(IMemoryBlockListener listener) {
171         
172         if(listeners == null) {
173             return;
174         }
175         if(listener == null) {
176             DebugPlugin.logMessage("Null argument passed into IMemoryBlockManager.addListener", null); //$NON-NLS-1$
177
return;
178         }
179         if (!listeners.contains(listener)) {
180             listeners.add(listener);
181         }
182     }
183
184     /* (non-Javadoc)
185      * @see org.eclipse.debug.ui.IMemoryBlockManager#removeListener(org.eclipse.debug.ui.IMemoryBlockListener)
186      */

187     public void removeListener(IMemoryBlockListener listener) {
188         
189         if(listeners == null) {
190             return;
191         }
192         if(listener == null) {
193             DebugPlugin.logMessage("Null argument passed into IMemoryBlockManager.removeListener", null); //$NON-NLS-1$
194
return;
195         }
196         if (listeners.contains(listener)) {
197             listeners.remove(listener);
198         }
199     }
200
201     /* (non-Javadoc)
202      * @see org.eclipse.debug.core.IMemoryBlockManager#getMemoryBlocks()
203      */

204     public IMemoryBlock[] getMemoryBlocks() {
205         return (IMemoryBlock[])memoryBlocks.toArray(new IMemoryBlock[memoryBlocks.size()]);
206     }
207
208     /* (non-Javadoc)
209      * @see org.eclipse.debug.ui.IMemoryBlockManager#getMemoryBlocks(org.eclipse.debug.core.model.IDebugTarget)
210      */

211     public IMemoryBlock[] getMemoryBlocks(IDebugTarget debugTarget) {
212         IMemoryBlock[] blocks = (IMemoryBlock[])memoryBlocks.toArray(new IMemoryBlock[memoryBlocks.size()]);
213         ArrayList JavaDoc memoryBlocksList = new ArrayList JavaDoc();
214         for (int i=0; i<blocks.length; i++) {
215             if (blocks[i].getDebugTarget() == debugTarget) {
216                 memoryBlocksList.add(blocks[i]);
217             }
218         }
219         return (IMemoryBlock[])memoryBlocksList.toArray(new IMemoryBlock[memoryBlocksList.size()]);
220     }
221     
222     /* (non-Javadoc)
223      * @see org.eclipse.debug.ui.IMemoryBlockManager#getMemoryBlocks(org.eclipse.debug.core.model.IMemoryBlockRetrieval)
224      */

225     public IMemoryBlock[] getMemoryBlocks(IMemoryBlockRetrieval retrieve) {
226         IMemoryBlock[] blocks = (IMemoryBlock[])memoryBlocks.toArray(new IMemoryBlock[memoryBlocks.size()]);
227         ArrayList JavaDoc memoryBlocksList = new ArrayList JavaDoc(blocks.length);
228         for (int i=0; i<blocks.length; i++) {
229             if (blocks[i] instanceof IMemoryBlockExtension) {
230                 if (((IMemoryBlockExtension)blocks[i]).getMemoryBlockRetrieval() == retrieve) {
231                     memoryBlocksList.add(blocks[i]);
232                 }
233             }
234             else {
235                 // standard memory block always uses the debug target as the memory block retrieval
236
if (blocks[i].getDebugTarget() == retrieve) {
237                     memoryBlocksList.add(blocks[i]);
238                 }
239             }
240         }
241         return (IMemoryBlock[])memoryBlocksList.toArray(new IMemoryBlock[memoryBlocksList.size()]);
242     }
243     
244     /**
245      * Notifies the listeners about the given memory blocks and the event to be sent
246      * @param memBlocks
247      * @param event
248      */

249     private void notifyListeners(IMemoryBlock[] memBlocks, int event) {
250         getMemoryBlockNotifier().notify(memBlocks, event);
251     }
252
253     /* (non-Javadoc)
254      * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
255      */

256     public void handleDebugEvents(DebugEvent[] events) {
257         for (int i=0; i < events.length; i++) {
258             handleDebugEvent(events[i]);
259         }
260     }
261     
262     /**
263      * Handles a debug event
264      * @param event
265      */

266     public void handleDebugEvent(DebugEvent event) {
267         Object JavaDoc obj = event.getSource();
268         IDebugTarget dt = null;
269         
270         if (event.getKind() == DebugEvent.TERMINATE) {
271             // a terminate event could happen from an IThread or IDebugTarget
272
// only handle a debug event from the debug target
273
if (obj instanceof IDebugTarget) {
274                 dt = ((IDebugTarget)obj);
275                 
276                 // getMemoryBlocks will return an empty array if it is null
277
IMemoryBlock[] deletedMemoryBlocks = getMemoryBlocks(dt);
278                 removeMemoryBlocks(deletedMemoryBlocks);
279             }
280         }
281     }
282     
283     /**
284      * Clean up when the plugin is shut down
285      */

286     public void shutdown() {
287         if (listeners != null) {
288             listeners.clear();
289             listeners = null;
290         }
291         
292         if (memoryBlocks != null) {
293             memoryBlocks.clear();
294             memoryBlocks = null;
295         }
296     }
297     
298 }
299
Popular Tags