1 19 20 package org.netbeans.modules.debugger.jpda.ui.models; 21 22 import java.util.Collection ; 23 import java.util.HashMap ; 24 import java.util.HashSet ; 25 import java.util.LinkedList ; 26 import java.util.List ; 27 import javax.security.auth.RefreshFailedException ; 28 import javax.security.auth.Refreshable ; 29 import javax.swing.Action ; 30 import org.netbeans.api.debugger.jpda.ObjectVariable; 31 import org.netbeans.api.debugger.jpda.Variable; 32 import org.netbeans.spi.debugger.ContextProvider; 33 import org.netbeans.spi.debugger.jpda.VariablesFilter; 34 import org.netbeans.spi.viewmodel.ModelEvent; 35 import org.netbeans.spi.viewmodel.ModelListener; 36 import org.netbeans.spi.viewmodel.NodeActionsProvider; 37 import org.netbeans.spi.viewmodel.NodeActionsProviderFilter; 38 import org.netbeans.spi.viewmodel.NodeModel; 39 import org.netbeans.spi.viewmodel.NodeModelFilter; 40 import org.netbeans.spi.viewmodel.TableModel; 41 import org.netbeans.spi.viewmodel.TableModelFilter; 42 import org.netbeans.spi.viewmodel.TreeModel; 43 import org.netbeans.spi.viewmodel.TreeModelFilter; 44 import org.netbeans.spi.viewmodel.UnknownTypeException; 45 import org.openide.util.RequestProcessor; 46 47 52 public class VariablesTreeModelFilter implements TreeModelFilter, 53 NodeModelFilter, TableModelFilter, NodeActionsProviderFilter, Runnable { 54 55 private ContextProvider lookupProvider; 56 57 private final Collection modelListeners = new HashSet (); 58 59 private RequestProcessor evaluationRP = new RequestProcessor(); 60 61 private RequestProcessor.Task evaluationTask; 62 63 private LinkedList evaluationQueue = new LinkedList (); 64 65 66 public VariablesTreeModelFilter (ContextProvider lookupProvider) { 67 this.lookupProvider = lookupProvider; 68 } 69 70 76 public Object getRoot (TreeModel original) { 77 return original.getRoot (); 78 } 79 80 static boolean isEvaluated(Object o) { 81 if (o instanceof Refreshable ) { 82 return ((Refreshable ) o).isCurrent(); 83 } 84 return true; 85 } 86 87 private static void waitToEvaluate(Object o) { 88 if (o instanceof Refreshable ) { 89 try { 91 ((Refreshable ) o).refresh(); 92 } catch (RefreshFailedException exc) { 93 Thread.currentThread().interrupt(); 95 } 96 } 97 } 98 99 private void postEvaluationMonitor(Object o, Runnable whenEvaluated) { 100 synchronized (evaluationQueue) { 101 if (evaluationQueue.contains(o) && 102 evaluationQueue.contains(whenEvaluated)) return ; 103 if (evaluationTask == null) { 104 evaluationTask = evaluationRP.create(this); 105 } 106 evaluationQueue.add(o); 107 evaluationQueue.add(whenEvaluated); 108 evaluationTask.schedule(1); 109 } 110 } 111 112 public void run() { 113 Object node; 114 do { 115 node = null; 116 Runnable whenEvaluated = null; 117 synchronized (evaluationQueue) { 118 if (!evaluationQueue.isEmpty()) { 119 node = evaluationQueue.removeFirst(); 120 whenEvaluated = (Runnable ) evaluationQueue.removeFirst(); 121 } 122 } 123 if (node != null) { 124 waitToEvaluate(node); 125 if (whenEvaluated != null) { 126 whenEvaluated.run(); 127 } else { 128 fireModelChange(new ModelEvent.NodeChanged(this, node)); 129 } 131 } 132 } while (node != null); 133 evaluationTask = null; 134 } 135 136 150 public Object [] getChildren ( 151 final TreeModel original, 152 final Object parent, 153 final int from, 154 final int to 155 ) throws UnknownTypeException { 156 Object [] ch; 157 VariablesFilter vf = getFilter (parent, true, new Runnable () { 158 public void run() { 159 fireModelChange(new ModelEvent.NodeChanged(VariablesTreeModelFilter.this, 160 parent, 161 ModelEvent.NodeChanged.CHILDREN_MASK)); 162 } 163 }); 164 if (vf == null) 165 ch = original.getChildren (parent, from, to); 166 else 167 ch = vf.getChildren (original, (Variable) parent, from, to); 168 return ch; 169 } 170 171 185 public int getChildrenCount ( 186 final TreeModel original, 187 final Object parent 188 ) throws UnknownTypeException { 189 VariablesFilter vf = getFilter (parent, true, new Runnable () { 190 public void run() { 191 fireModelChange(new ModelEvent.NodeChanged(VariablesTreeModelFilter.this, 192 parent, 193 ModelEvent.NodeChanged.CHILDREN_MASK)); 194 } 195 }); 196 int count; 197 if (vf == null) { 198 count = original.getChildrenCount (parent); 199 } else { 200 count = vf.getChildrenCount (original, (Variable) parent); 201 } 202 return count; 203 } 204 205 213 public boolean isLeaf ( 214 TreeModel original, 215 Object node 216 ) throws UnknownTypeException { 217 VariablesFilter vf = getFilter (node, true, null); 218 if (vf == null) 219 return original.isLeaf (node); 220 return vf.isLeaf (original, (Variable) node); 221 } 222 223 public void addModelListener (ModelListener l) { 224 synchronized (modelListeners) { 225 modelListeners.add(l); 226 } 227 } 228 229 public void removeModelListener (ModelListener l) { 230 synchronized (modelListeners) { 231 modelListeners.remove(l); 232 } 233 } 234 235 private void fireModelChange(ModelEvent me) { 236 Object [] listeners; 237 synchronized (modelListeners) { 238 listeners = modelListeners.toArray(); 239 } 240 for (int i = 0; i < listeners.length; i++) { 241 ((ModelListener) listeners[i]).modelChanged(me); 242 } 243 } 244 245 246 248 public String getDisplayName (final NodeModel original, final Object node) 249 throws UnknownTypeException { 250 final String [] unfilteredDisplayName = new String [] { null }; 251 VariablesFilter vf = getFilter (node, true, new Runnable () { 252 public void run() { 253 VariablesFilter vf = getFilter (node, false, null); 254 if (vf == null) return ; 255 String filteredDisplayName; 256 try { 257 filteredDisplayName = vf.getDisplayName (original, (Variable) node); 258 } catch (UnknownTypeException utex) { 259 filteredDisplayName = utex.toString(); 261 } 262 if (!filteredDisplayName.equals(unfilteredDisplayName[0])) { 263 fireModelChange(new ModelEvent.NodeChanged(VariablesTreeModelFilter.this, 264 node, ModelEvent.NodeChanged.DISPLAY_NAME_MASK)); 265 } 266 } 267 }); 268 if (vf == null) { 269 String displayName = original.getDisplayName (node); 270 unfilteredDisplayName[0] = displayName; 271 return displayName; 272 } else { 273 return vf.getDisplayName (original, (Variable) node); 274 } 275 } 276 277 public String getIconBase (final NodeModel original, final Object node) 278 throws UnknownTypeException { 279 final String [] unfilteredIconBase = new String [] { null }; 280 VariablesFilter vf = getFilter (node, true, new Runnable () { 281 public void run() { 282 VariablesFilter vf = getFilter (node, false, null); 283 if (vf == null) return ; 284 String filteredIconBase; 285 try { 286 filteredIconBase = vf.getIconBase (original, (Variable) node); 287 } catch (UnknownTypeException utex) { 288 filteredIconBase = utex.toString(); 290 } 291 if (!filteredIconBase.equals(unfilteredIconBase[0])) { 292 fireModelChange(new ModelEvent.NodeChanged(VariablesTreeModelFilter.this, 293 node, ModelEvent.NodeChanged.ICON_MASK)); 294 } 295 } 296 }); 297 if (vf == null) { 298 String iconBase = original.getIconBase (node); 299 unfilteredIconBase[0] = iconBase; 300 return iconBase; 301 } else { 302 return vf.getIconBase (original, (Variable) node); 303 } 304 } 305 306 public String getShortDescription (final NodeModel original, final Object node) 307 throws UnknownTypeException { 308 final String [] unfilteredShortDescription = new String [] { null }; 309 VariablesFilter vf = getFilter (node, true, new Runnable () { 310 public void run() { 311 VariablesFilter vf = getFilter (node, false, null); 312 if (vf == null) return ; 313 String filteredShortDescription; 314 try { 315 filteredShortDescription = vf.getShortDescription (original, (Variable) node); 316 } catch (UnknownTypeException utex) { 317 filteredShortDescription = utex.toString(); 319 } 320 if (!filteredShortDescription.equals(unfilteredShortDescription[0])) { 321 fireModelChange(new ModelEvent.NodeChanged(VariablesTreeModelFilter.this, 322 node, ModelEvent.NodeChanged.SHORT_DESCRIPTION_MASK)); 323 } 324 } 325 }); 326 if (vf == null) { 327 return original.getShortDescription (node); 328 } else { 329 return vf.getShortDescription (original, (Variable) node); 330 } 331 } 332 333 334 336 public Action [] getActions ( 337 NodeActionsProvider original, 338 Object node 339 ) throws UnknownTypeException { 340 VariablesFilter vf = getFilter (node, true, null); 341 if (vf == null) 342 return original.getActions (node); 343 return vf.getActions (original, (Variable) node); 344 } 345 346 public void performDefaultAction ( 347 NodeActionsProvider original, 348 Object node 349 ) throws UnknownTypeException { 350 VariablesFilter vf = getFilter (node, true, null); 351 if (vf == null) 352 original.performDefaultAction (node); 353 else 354 vf.performDefaultAction (original, (Variable) node); 355 } 356 357 358 360 public Object getValueAt ( 361 TableModel original, 362 Object row, 363 String columnID 364 ) throws UnknownTypeException { 365 Object value; 366 VariablesFilter vf = getFilter (row, false, null); 367 if (vf == null) { 368 value = original.getValueAt (row, columnID); 369 } else { 370 value = vf.getValueAt (original, (Variable) row, columnID); 371 } 372 return value; 373 } 374 375 public boolean isReadOnly ( 376 TableModel original, 377 Object row, 378 String columnID 379 ) throws UnknownTypeException { 380 VariablesFilter vf = getFilter (row, true, null); 381 if (vf == null) 382 return original.isReadOnly (row, columnID); 383 return vf.isReadOnly (original, (Variable) row, columnID); 384 } 385 386 public void setValueAt ( 387 TableModel original, 388 Object row, 389 String columnID, 390 Object value 391 ) throws UnknownTypeException { 392 VariablesFilter vf = getFilter (row, false, null); 393 if (vf == null) 394 original.setValueAt (row, columnID, value); 395 else 396 vf.setValueAt (original, (Variable) row, columnID, value); 397 } 398 399 400 402 private HashMap typeToFilter; 403 private HashMap ancestorToFilter; 404 405 413 private VariablesFilter getFilter (Object o, boolean checkEvaluated, Runnable whenEvaluated) { 414 if (typeToFilter == null) { 415 typeToFilter = new HashMap (); 416 ancestorToFilter = new HashMap (); 417 List l = lookupProvider.lookup (null, VariablesFilter.class); 418 int i, k = l.size (); 419 for (i = 0; i < k; i++) { 420 VariablesFilter f = (VariablesFilter) l.get (i); 421 String [] types = f.getSupportedAncestors (); 422 int j, jj = types.length; 423 for (j = 0; j < jj; j++) 424 ancestorToFilter.put (types [j], f); 425 types = f.getSupportedTypes (); 426 jj = types.length; 427 for (j = 0; j < jj; j++) 428 typeToFilter.put (types [j], f); 429 } 430 } 431 432 if (typeToFilter.size() == 0) return null; 434 if (!(o instanceof Variable)) return null; 435 436 Variable v = (Variable) o; 437 438 if (checkEvaluated) { 439 if (!isEvaluated(v)) { 440 if (whenEvaluated != null) { 441 postEvaluationMonitor(o, whenEvaluated); 442 } 443 return null; 444 } 445 } 446 447 String type = v.getType (); 448 VariablesFilter vf = (VariablesFilter) typeToFilter.get (type); 449 if (vf != null) return vf; 450 451 if (!(o instanceof ObjectVariable)) return null; 452 ObjectVariable ov = (ObjectVariable) o; 453 ov = ov.getSuper (); 454 while (ov != null) { 455 type = ov.getType (); 456 vf = (VariablesFilter) ancestorToFilter.get (type); 457 if (vf != null) return vf; 458 ov = ov.getSuper (); 459 } 460 return null; 461 } 462 463 } 464 | Popular Tags |