KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.core;
12
13  
14 import java.io.IOException JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Vector JavaDoc;
21
22 import javax.xml.parsers.ParserConfigurationException JavaDoc;
23 import javax.xml.transform.TransformerException JavaDoc;
24
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IConfigurationElement;
27 import org.eclipse.core.runtime.IExtensionPoint;
28 import org.eclipse.core.runtime.ISafeRunnable;
29 import org.eclipse.core.runtime.IStatus;
30 import org.eclipse.core.runtime.ListenerList;
31 import org.eclipse.core.runtime.Platform;
32 import org.eclipse.core.runtime.PlatformObject;
33 import org.eclipse.core.runtime.Preferences;
34 import org.eclipse.core.runtime.SafeRunner;
35 import org.eclipse.core.runtime.Status;
36 import org.eclipse.debug.core.DebugPlugin;
37 import org.eclipse.debug.core.IExpressionListener;
38 import org.eclipse.debug.core.IExpressionManager;
39 import org.eclipse.debug.core.IExpressionsListener;
40 import org.eclipse.debug.core.model.IExpression;
41 import org.eclipse.debug.core.model.IWatchExpression;
42 import org.eclipse.debug.core.model.IWatchExpressionDelegate;
43 import org.w3c.dom.Document JavaDoc;
44 import org.w3c.dom.Element JavaDoc;
45 import org.w3c.dom.Node JavaDoc;
46 import org.w3c.dom.NodeList JavaDoc;
47
48 import com.ibm.icu.text.MessageFormat;
49
50 /**
51  * The expression manager manages all registered expressions
52  * for the debug plug-in. It is instantiated by the debug plug-in
53  * at startup.
54  *
55  * @see IExpressionManager
56  */

57 public class ExpressionManager extends PlatformObject implements IExpressionManager {
58     
59     /**
60      * Collection of registered expressions.
61      */

62     private Vector JavaDoc fExpressions = null;
63     
64     /**
65      * List of expression listeners
66      */

67     private ListenerList fListeners = null;
68     
69     /**
70      * List of expressions listeners (plural)
71      */

72     private ListenerList fExpressionsListeners = null;
73     
74     /**
75      * Mapping of debug model identifiers (String) to
76      * expression delegate extensions (IConfigurationElement)
77      */

78     private Map JavaDoc fWatchExpressionDelegates= new HashMap JavaDoc();
79     
80     // Constants for add/remove/change notification
81
private static final int ADDED = 1;
82     private static final int CHANGED = 2;
83     private static final int REMOVED = 3;
84
85     // Preference for persisted watch expressions
86
private static final String JavaDoc PREF_WATCH_EXPRESSIONS= "prefWatchExpressions"; //$NON-NLS-1$
87
// Persisted watch expression XML tags
88
private static final String JavaDoc WATCH_EXPRESSIONS_TAG= "watchExpressions"; //$NON-NLS-1$
89
private static final String JavaDoc EXPRESSION_TAG= "expression"; //$NON-NLS-1$
90
private static final String JavaDoc TEXT_TAG= "text"; //$NON-NLS-1$
91
private static final String JavaDoc ENABLED_TAG= "enabled"; //$NON-NLS-1$
92
// XML values
93
private static final String JavaDoc TRUE_VALUE= "true"; //$NON-NLS-1$
94
private static final String JavaDoc FALSE_VALUE= "false"; //$NON-NLS-1$
95

96     public ExpressionManager() {
97         loadPersistedExpressions();
98         loadWatchExpressionDelegates();
99     }
100     
101     /**
102      * Loads the mapping of debug models to watch expression delegates
103      * from the org.eclipse.debug.core.watchExpressionDelegates
104      * extension point.
105      */

106     private void loadWatchExpressionDelegates() {
107         IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), "watchExpressionDelegates"); //$NON-NLS-1$
108
IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements();
109         for (int i = 0; i < configurationElements.length; i++) {
110             IConfigurationElement element = configurationElements[i];
111             if (element.getName().equals("watchExpressionDelegate")) { //$NON-NLS-1$
112
String JavaDoc debugModel = element.getAttribute("debugModel"); //$NON-NLS-1$
113
if (debugModel == null || debugModel.length() == 0) {
114                     continue;
115                 }
116                 fWatchExpressionDelegates.put(debugModel, element);
117             }
118         }
119     }
120     
121     /* (non-Javadoc)
122      * @see org.eclipse.debug.core.IExpressionManager#newWatchExpressionDelegate(java.lang.String)
123      */

124     public IWatchExpressionDelegate newWatchExpressionDelegate(String JavaDoc debugModel) {
125         try {
126             IConfigurationElement element= (IConfigurationElement) fWatchExpressionDelegates.get(debugModel);
127             if (element != null) {
128                 return (IWatchExpressionDelegate) element.createExecutableExtension("delegateClass"); //$NON-NLS-1$
129
}
130             return null;
131         } catch (CoreException e) {
132             DebugPlugin.log(e);
133             return null;
134         }
135     }
136
137     /* (non-Javadoc)
138      * @see org.eclipse.debug.core.IExpressionManager#hasWatchExpressionDelegate(java.lang.String)
139      */

140     public boolean hasWatchExpressionDelegate(String JavaDoc id) {
141         IConfigurationElement element= (IConfigurationElement) fWatchExpressionDelegates.get(id);
142         return element != null;
143     }
144     
145     /**
146      * Loads any persisted watch expressions from the preferences.
147      * NOTE: It's important that no setter methods are called on
148      * the watchpoints which will fire change events as this
149      * will cause an infinite loop (see Bug 27281).
150      */

151     private void loadPersistedExpressions() {
152         String JavaDoc expressionsString= DebugPlugin.getDefault().getPluginPreferences().getString(PREF_WATCH_EXPRESSIONS);
153         if (expressionsString.length() == 0) {
154             return;
155         }
156         Element root;
157         try {
158             root = DebugPlugin.parseDocument(expressionsString);
159         } catch (CoreException e) {
160             DebugPlugin.logMessage("An exception occurred while loading watch expressions.", e); //$NON-NLS-1$
161
return;
162         }
163         if (!root.getNodeName().equals(WATCH_EXPRESSIONS_TAG)) {
164             DebugPlugin.logMessage("Invalid format encountered while loading watch expressions.", null); //$NON-NLS-1$
165
return;
166         }
167         NodeList JavaDoc list= root.getChildNodes();
168         for (int i= 0, numItems= list.getLength(); i < numItems; i++) {
169             Node JavaDoc node= list.item(i);
170             if (node.getNodeType() == Node.ELEMENT_NODE) {
171                 Element element= (Element) node;
172                 if (!element.getNodeName().equals(EXPRESSION_TAG)) {
173                     DebugPlugin.logMessage(MessageFormat.format("Invalid XML element encountered while loading watch expressions: {0}", new String JavaDoc[] {node.getNodeName()}), null); //$NON-NLS-1$
174
continue;
175                 }
176                 String JavaDoc expressionText= element.getAttribute(TEXT_TAG);
177                 if (expressionText.length() > 0) {
178                     boolean enabled= TRUE_VALUE.equals(element.getAttribute(ENABLED_TAG));
179                     IWatchExpression expression= newWatchExpression(expressionText, enabled);
180                     if (fExpressions == null) {
181                         fExpressions= new Vector JavaDoc(list.getLength());
182                     }
183                     fExpressions.add(expression);
184                 } else {
185                     DebugPlugin.logMessage("Invalid expression entry encountered while loading watch expressions. Expression text is empty.", null); //$NON-NLS-1$
186
}
187             }
188         }
189     }
190     
191     /**
192      * Creates a new watch expression with the given expression
193      * and the given enablement;
194      *
195      * @param expressionText the text of the expression to be evaluated
196      * @param enabled whether or not the new expression should be enabled
197      * @return the new watch expression
198      */

199     private IWatchExpression newWatchExpression(String JavaDoc expressionText, boolean enabled) {
200         return new WatchExpression(expressionText, enabled);
201     }
202
203     /**
204      * @see IExpressionManager#newWatchExpression(String)
205      */

206     public IWatchExpression newWatchExpression(String JavaDoc expressionText) {
207         return new WatchExpression(expressionText);
208     }
209     
210     /**
211      * Persists this manager's watch expressions as XML in the
212      * preference store.
213      */

214     public void storeWatchExpressions() {
215         Preferences prefs= DebugPlugin.getDefault().getPluginPreferences();
216         String JavaDoc expressionString= ""; //$NON-NLS-1$
217
try {
218             expressionString= getWatchExpressionsAsXML();
219         } catch (IOException JavaDoc e) {
220             DebugPlugin.log(e);
221         } catch (ParserConfigurationException JavaDoc e) {
222             DebugPlugin.log(e);
223         } catch (TransformerException JavaDoc e) {
224             DebugPlugin.log(e);
225         }
226         prefs.setValue(PREF_WATCH_EXPRESSIONS, expressionString);
227     }
228
229     /**
230      * Returns this manager's watch expressions as XML.
231      * @return this manager's watch expressions as XML
232      * @throws IOException if an exception occurs while creating
233      * the XML document.
234      * @throws ParserConfigurationException if an exception occurs while creating
235      * the XML document.
236      * @throws TransformerException if an exception occurs while creating
237      * the XML document.
238      */

239     private String JavaDoc getWatchExpressionsAsXML() throws IOException JavaDoc, ParserConfigurationException JavaDoc, TransformerException JavaDoc {
240         IExpression[] expressions= getExpressions();
241         Document JavaDoc document= LaunchManager.getDocument();
242         Element rootElement= document.createElement(WATCH_EXPRESSIONS_TAG);
243         document.appendChild(rootElement);
244         for (int i = 0; i < expressions.length; i++) {
245             IExpression expression= expressions[i];
246             if (expression instanceof IWatchExpression) {
247                 Element element= document.createElement(EXPRESSION_TAG);
248                 element.setAttribute(TEXT_TAG, expression.getExpressionText());
249                 element.setAttribute(ENABLED_TAG, ((IWatchExpression) expression).isEnabled() ? TRUE_VALUE : FALSE_VALUE);
250                 rootElement.appendChild(element);
251             }
252         }
253         return LaunchManager.serializeDocument(document);
254     }
255
256     /**
257      * @see IExpressionManager#addExpression(IExpression)
258      */

259     public void addExpression(IExpression expression) {
260         addExpressions(new IExpression[]{expression});
261     }
262     
263     /**
264      * @see IExpressionManager#addExpressions(IExpression[])
265      */

266     public void addExpressions(IExpression[] expressions) {
267         if (fExpressions == null) {
268             fExpressions = new Vector JavaDoc(expressions.length);
269         }
270         boolean addedWatchExpression= false;
271         List JavaDoc added = new ArrayList JavaDoc(expressions.length);
272         for (int i = 0; i < expressions.length; i++) {
273             IExpression expression = expressions[i];
274             if (fExpressions.indexOf(expression) == -1) {
275                 added.add(expression);
276                 fExpressions.add(expression);
277                 if (expression instanceof IWatchExpression) {
278                     addedWatchExpression= true;
279                 }
280             }
281         }
282         if (!added.isEmpty()) {
283             fireUpdate((IExpression[])added.toArray(new IExpression[added.size()]), ADDED);
284         }
285         if (addedWatchExpression) {
286             storeWatchExpressions();
287         }
288     }
289
290     /**
291      * @see IExpressionManager#getExpressions()
292      */

293     public IExpression[] getExpressions() {
294         if (fExpressions == null) {
295             return new IExpression[0];
296         }
297         IExpression[] temp= new IExpression[fExpressions.size()];
298         fExpressions.copyInto(temp);
299         return temp;
300     }
301
302     /**
303      * @see IExpressionManager#getExpressions(String)
304      */

305     public IExpression[] getExpressions(String JavaDoc modelIdentifier) {
306         if (fExpressions == null) {
307             return new IExpression[0];
308         }
309         ArrayList JavaDoc temp= new ArrayList JavaDoc(fExpressions.size());
310         Iterator JavaDoc iter= fExpressions.iterator();
311         while (iter.hasNext()) {
312             IExpression expression= (IExpression) iter.next();
313             String JavaDoc id= expression.getModelIdentifier();
314             if (id != null && id.equals(modelIdentifier)) {
315                 temp.add(expression);
316             }
317         }
318         return (IExpression[]) temp.toArray(new IExpression[temp.size()]);
319     }
320
321     /**
322      * @see IExpressionManager#removeExpression(IExpression)
323      */

324     public void removeExpression(IExpression expression) {
325         removeExpressions(new IExpression[] {expression});
326     }
327
328     /**
329      * @see IExpressionManager#removeExpressions(IExpression[])
330      */

331     public void removeExpressions(IExpression[] expressions) {
332         if (fExpressions == null) {
333             return;
334         }
335         List JavaDoc removed = new ArrayList JavaDoc(expressions.length);
336         for (int i = 0; i < expressions.length; i++) {
337             IExpression expression = expressions[i];
338             if (fExpressions.remove(expression)) {
339                 removed.add(expression);
340                 expression.dispose();
341             }
342         }
343         if (!removed.isEmpty()) {
344             fireUpdate((IExpression[])removed.toArray(new IExpression[removed.size()]), REMOVED);
345             storeWatchExpressions();
346         }
347     }
348     
349     /**
350      * @see IExpressionManager#addExpressionListener(IExpressionListener)
351      */

352     public void addExpressionListener(IExpressionListener listener) {
353         if (fListeners == null) {
354             fListeners = new ListenerList();
355         }
356         fListeners.add(listener);
357     }
358
359     /**
360      * @see IExpressionManager#removeExpressionListener(IExpressionListener)
361      */

362     public void removeExpressionListener(IExpressionListener listener) {
363         if (fListeners == null) {
364             return;
365         }
366         fListeners.remove(listener);
367     }
368     
369     /**
370      * The given watch expression has changed. Update the persisted
371      * expressions to store this change as indicated
372      *
373      * @param expression the changed expression
374      * @param persist whether to persist the expressions
375      */

376     protected void watchExpressionChanged(IWatchExpression expression, boolean persist) {
377         if (fExpressions != null && fExpressions.contains(expression)) {
378             if (persist) {
379                 storeWatchExpressions();
380             }
381             fireUpdate(new IExpression[]{expression}, CHANGED);
382         }
383     }
384
385     /**
386      * Notifies listeners of the adds/removes/changes
387      *
388      * @param breakpoints associated breakpoints
389      * @param deltas or <code>null</code>
390      * @param update type of change
391      */

392     private void fireUpdate(IExpression[] expressions, int update) {
393         // single listeners
394
getExpressionNotifier().notify(expressions, update);
395         
396         // multi listeners
397
getExpressionsNotifier().notify(expressions, update);
398     }
399
400     /**
401      * @see IExpressionManager#hasExpressions()
402      */

403     public boolean hasExpressions() {
404         return fExpressions != null && !fExpressions.isEmpty();
405     }
406
407     /**
408      * @see org.eclipse.debug.core.IExpressionManager#addExpressionListener(org.eclipse.debug.core.IExpressionsListener)
409      */

410     public void addExpressionListener(IExpressionsListener listener) {
411         if (fExpressionsListeners == null) {
412             fExpressionsListeners = new ListenerList();
413         }
414         fExpressionsListeners.add(listener);
415     }
416
417     /**
418      * @see org.eclipse.debug.core.IExpressionManager#removeExpressionListener(org.eclipse.debug.core.IExpressionsListener)
419      */

420     public void removeExpressionListener(IExpressionsListener listener) {
421         if (fExpressionsListeners == null) {
422             return;
423         }
424         fExpressionsListeners.remove(listener);
425     }
426     
427     private ExpressionNotifier getExpressionNotifier() {
428         return new ExpressionNotifier();
429     }
430     
431     /**
432      * Notifies an expression listener (single expression) in a safe runnable to
433      * handle exceptions.
434      */

435     class ExpressionNotifier implements ISafeRunnable {
436         
437         private IExpressionListener fListener;
438         private int fType;
439         private IExpression fExpression;
440         
441         /**
442          * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
443          */

444         public void handleException(Throwable JavaDoc exception) {
445             IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during expression change notification.", exception); //$NON-NLS-1$
446
DebugPlugin.log(status);
447         }
448
449         /**
450          * @see org.eclipse.core.runtime.ISafeRunnable#run()
451          */

452         public void run() throws Exception JavaDoc {
453             switch (fType) {
454                 case ADDED:
455                     fListener.expressionAdded(fExpression);
456                     break;
457                 case REMOVED:
458                     fListener.expressionRemoved(fExpression);
459                     break;
460                 case CHANGED:
461                     fListener.expressionChanged(fExpression);
462                     break;
463             }
464         }
465
466         /**
467          * Notifies listeners of the add/change/remove
468          *
469          * @param expressions the expressions that have changed
470          * @param update the type of change
471          */

472         public void notify(IExpression[] expressions, int update) {
473             if (fListeners != null) {
474                 fType = update;
475                 Object JavaDoc[] copiedListeners= fListeners.getListeners();
476                 for (int i= 0; i < copiedListeners.length; i++) {
477                     fListener = (IExpressionListener)copiedListeners[i];
478                     for (int j = 0; j < expressions.length; j++) {
479                         fExpression = expressions[j];
480                         SafeRunner.run(this);
481                     }
482                 }
483             }
484             fListener = null;
485             fExpression = null;
486         }
487     }
488     
489     private ExpressionsNotifier getExpressionsNotifier() {
490         return new ExpressionsNotifier();
491     }
492     
493     /**
494      * Notifies an expression listener (multiple expressions) in a safe runnable
495      * to handle exceptions.
496      */

497     class ExpressionsNotifier implements ISafeRunnable {
498         
499         private IExpressionsListener fListener;
500         private int fType;
501         private IExpression[] fNotifierExpressions;
502         
503         /**
504          * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
505          */

506         public void handleException(Throwable JavaDoc exception) {
507             IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during expression change notification.", exception); //$NON-NLS-1$
508
DebugPlugin.log(status);
509         }
510
511         /**
512          * @see org.eclipse.core.runtime.ISafeRunnable#run()
513          */

514         public void run() throws Exception JavaDoc {
515             switch (fType) {
516                 case ADDED:
517                     fListener.expressionsAdded(fNotifierExpressions);
518                     break;
519                 case REMOVED:
520                     fListener.expressionsRemoved(fNotifierExpressions);
521                     break;
522                 case CHANGED:
523                     fListener.expressionsChanged(fNotifierExpressions);
524                     break;
525             }
526         }
527
528         /**
529          * Notifies listeners of the adds/changes/removes
530          *
531          * @param expressions the expressions that changed
532          * @param update the type of change
533          */

534         public void notify(IExpression[] expressions, int update) {
535             if (fExpressionsListeners != null) {
536                 fNotifierExpressions = expressions;
537                 fType = update;
538                 Object JavaDoc[] copiedListeners = fExpressionsListeners.getListeners();
539                 for (int i= 0; i < copiedListeners.length; i++) {
540                     fListener = (IExpressionsListener)copiedListeners[i];
541                     SafeRunner.run(this);
542                 }
543             }
544             fNotifierExpressions = null;
545             fListener = null;
546         }
547     }
548 }
549
Popular Tags