1 11 package org.eclipse.debug.internal.core; 12 13 14 import java.io.IOException ; 15 import java.util.ArrayList ; 16 import java.util.HashMap ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Map ; 20 import java.util.Vector ; 21 22 import javax.xml.parsers.ParserConfigurationException ; 23 import javax.xml.transform.TransformerException ; 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 ; 44 import org.w3c.dom.Element ; 45 import org.w3c.dom.Node ; 46 import org.w3c.dom.NodeList ; 47 48 import com.ibm.icu.text.MessageFormat; 49 50 57 public class ExpressionManager extends PlatformObject implements IExpressionManager { 58 59 62 private Vector fExpressions = null; 63 64 67 private ListenerList fListeners = null; 68 69 72 private ListenerList fExpressionsListeners = null; 73 74 78 private Map fWatchExpressionDelegates= new HashMap (); 79 80 private static final int ADDED = 1; 82 private static final int CHANGED = 2; 83 private static final int REMOVED = 3; 84 85 private static final String PREF_WATCH_EXPRESSIONS= "prefWatchExpressions"; private static final String WATCH_EXPRESSIONS_TAG= "watchExpressions"; private static final String EXPRESSION_TAG= "expression"; private static final String TEXT_TAG= "text"; private static final String ENABLED_TAG= "enabled"; private static final String TRUE_VALUE= "true"; private static final String FALSE_VALUE= "false"; 96 public ExpressionManager() { 97 loadPersistedExpressions(); 98 loadWatchExpressionDelegates(); 99 } 100 101 106 private void loadWatchExpressionDelegates() { 107 IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), "watchExpressionDelegates"); IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements(); 109 for (int i = 0; i < configurationElements.length; i++) { 110 IConfigurationElement element = configurationElements[i]; 111 if (element.getName().equals("watchExpressionDelegate")) { String debugModel = element.getAttribute("debugModel"); if (debugModel == null || debugModel.length() == 0) { 114 continue; 115 } 116 fWatchExpressionDelegates.put(debugModel, element); 117 } 118 } 119 } 120 121 124 public IWatchExpressionDelegate newWatchExpressionDelegate(String debugModel) { 125 try { 126 IConfigurationElement element= (IConfigurationElement) fWatchExpressionDelegates.get(debugModel); 127 if (element != null) { 128 return (IWatchExpressionDelegate) element.createExecutableExtension("delegateClass"); } 130 return null; 131 } catch (CoreException e) { 132 DebugPlugin.log(e); 133 return null; 134 } 135 } 136 137 140 public boolean hasWatchExpressionDelegate(String id) { 141 IConfigurationElement element= (IConfigurationElement) fWatchExpressionDelegates.get(id); 142 return element != null; 143 } 144 145 151 private void loadPersistedExpressions() { 152 String 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); return; 162 } 163 if (!root.getNodeName().equals(WATCH_EXPRESSIONS_TAG)) { 164 DebugPlugin.logMessage("Invalid format encountered while loading watch expressions.", null); return; 166 } 167 NodeList list= root.getChildNodes(); 168 for (int i= 0, numItems= list.getLength(); i < numItems; i++) { 169 Node 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 [] {node.getNodeName()}), null); continue; 175 } 176 String 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 (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); } 187 } 188 } 189 } 190 191 199 private IWatchExpression newWatchExpression(String expressionText, boolean enabled) { 200 return new WatchExpression(expressionText, enabled); 201 } 202 203 206 public IWatchExpression newWatchExpression(String expressionText) { 207 return new WatchExpression(expressionText); 208 } 209 210 214 public void storeWatchExpressions() { 215 Preferences prefs= DebugPlugin.getDefault().getPluginPreferences(); 216 String expressionString= ""; try { 218 expressionString= getWatchExpressionsAsXML(); 219 } catch (IOException e) { 220 DebugPlugin.log(e); 221 } catch (ParserConfigurationException e) { 222 DebugPlugin.log(e); 223 } catch (TransformerException e) { 224 DebugPlugin.log(e); 225 } 226 prefs.setValue(PREF_WATCH_EXPRESSIONS, expressionString); 227 } 228 229 239 private String getWatchExpressionsAsXML() throws IOException , ParserConfigurationException , TransformerException { 240 IExpression[] expressions= getExpressions(); 241 Document 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 259 public void addExpression(IExpression expression) { 260 addExpressions(new IExpression[]{expression}); 261 } 262 263 266 public void addExpressions(IExpression[] expressions) { 267 if (fExpressions == null) { 268 fExpressions = new Vector (expressions.length); 269 } 270 boolean addedWatchExpression= false; 271 List added = new ArrayList (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 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 305 public IExpression[] getExpressions(String modelIdentifier) { 306 if (fExpressions == null) { 307 return new IExpression[0]; 308 } 309 ArrayList temp= new ArrayList (fExpressions.size()); 310 Iterator iter= fExpressions.iterator(); 311 while (iter.hasNext()) { 312 IExpression expression= (IExpression) iter.next(); 313 String 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 324 public void removeExpression(IExpression expression) { 325 removeExpressions(new IExpression[] {expression}); 326 } 327 328 331 public void removeExpressions(IExpression[] expressions) { 332 if (fExpressions == null) { 333 return; 334 } 335 List removed = new ArrayList (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 352 public void addExpressionListener(IExpressionListener listener) { 353 if (fListeners == null) { 354 fListeners = new ListenerList(); 355 } 356 fListeners.add(listener); 357 } 358 359 362 public void removeExpressionListener(IExpressionListener listener) { 363 if (fListeners == null) { 364 return; 365 } 366 fListeners.remove(listener); 367 } 368 369 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 392 private void fireUpdate(IExpression[] expressions, int update) { 393 getExpressionNotifier().notify(expressions, update); 395 396 getExpressionsNotifier().notify(expressions, update); 398 } 399 400 403 public boolean hasExpressions() { 404 return fExpressions != null && !fExpressions.isEmpty(); 405 } 406 407 410 public void addExpressionListener(IExpressionsListener listener) { 411 if (fExpressionsListeners == null) { 412 fExpressionsListeners = new ListenerList(); 413 } 414 fExpressionsListeners.add(listener); 415 } 416 417 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 435 class ExpressionNotifier implements ISafeRunnable { 436 437 private IExpressionListener fListener; 438 private int fType; 439 private IExpression fExpression; 440 441 444 public void handleException(Throwable exception) { 445 IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during expression change notification.", exception); DebugPlugin.log(status); 447 } 448 449 452 public void run() throws Exception { 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 472 public void notify(IExpression[] expressions, int update) { 473 if (fListeners != null) { 474 fType = update; 475 Object [] 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 497 class ExpressionsNotifier implements ISafeRunnable { 498 499 private IExpressionsListener fListener; 500 private int fType; 501 private IExpression[] fNotifierExpressions; 502 503 506 public void handleException(Throwable exception) { 507 IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during expression change notification.", exception); DebugPlugin.log(status); 509 } 510 511 514 public void run() throws Exception { 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 534 public void notify(IExpression[] expressions, int update) { 535 if (fExpressionsListeners != null) { 536 fNotifierExpressions = expressions; 537 fType = update; 538 Object [] 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 |