1 19 20 package org.netbeans.modules.debugger.jpda.ui.models; 21 22 import java.awt.event.ActionEvent ; 23 import java.beans.PropertyChangeEvent ; 24 import java.beans.PropertyChangeListener ; 25 import java.lang.ref.WeakReference ; 26 import java.util.*; 27 import javax.swing.AbstractAction ; 28 import javax.swing.Action ; 29 30 import org.netbeans.api.debugger.Breakpoint; 31 import org.netbeans.api.debugger.Properties; 32 import org.netbeans.spi.debugger.ContextProvider; 33 import org.netbeans.api.debugger.jpda.JPDADebugger; 34 import org.netbeans.modules.debugger.jpda.ui.SourcePath; 35 import org.netbeans.spi.viewmodel.ColumnModel; 36 import org.netbeans.spi.viewmodel.Models; 37 import org.netbeans.spi.viewmodel.NodeActionsProvider; 38 import org.netbeans.spi.viewmodel.TableModel; 39 import org.netbeans.spi.viewmodel.TreeModel; 40 import org.netbeans.spi.viewmodel.ModelListener; 41 import org.netbeans.spi.viewmodel.UnknownTypeException; 42 import org.openide.DialogDisplayer; 43 import org.openide.NotifyDescriptor; 44 import org.openide.util.NbBundle; 45 46 47 50 public class SourcesModel implements TreeModel, TableModel, 51 NodeActionsProvider { 52 53 private static final String FILTER_PREFIX = "Do not stop in: "; 54 private static final String DISP_FILTER_PREFIX = NbBundle.getBundle 55 (SourcesModel.class).getString ("CTL_SourcesModel_Name_DoNotStopIn"); 56 57 58 private Listener listener; 59 private SourcePath sourcePath; 60 private JPDADebugger debugger; 61 private Vector listeners = new Vector (); 62 private Set filters = new HashSet (); 64 private Set enabledFilters = new HashSet (); 65 private Set enabledSourceRoots = new HashSet (); 66 private Set disabledSourceRoots = new HashSet (); 67 private Properties filterProperties = Properties. 68 getDefault ().getProperties ("debugger").getProperties ("sources"); 69 70 71 public SourcesModel (ContextProvider lookupProvider) { 72 sourcePath = (SourcePath) lookupProvider. 73 lookupFirst (null, SourcePath.class); 74 debugger = (JPDADebugger) lookupProvider. 75 lookupFirst (null, JPDADebugger.class); 76 loadFilters (); 77 } 78 79 80 82 86 public Object getRoot () { 87 return ROOT; 88 } 89 90 94 public Object [] getChildren (Object parent, int from, int to) 95 throws UnknownTypeException { 96 if (parent == ROOT) { 97 String [] sourceRoots = sourcePath.getOriginalSourceRoots (); 99 100 String [] ep = new String [filters.size ()]; 102 ep = (String []) filters.toArray (ep); 103 int i, k = ep.length; 104 for (i = 0; i < k; i++) { 105 ep [i] = DISP_FILTER_PREFIX + ep [i]; 106 } 107 108 Object [] os = new Object [sourceRoots.length + ep.length]; 110 System.arraycopy (sourceRoots, 0, os, 0, sourceRoots.length); 111 System.arraycopy (ep, 0, os, sourceRoots.length, ep.length); 112 to = Math.min(os.length, to); 113 from = Math.min(os.length, from); 114 Object [] fos = new Object [to - from]; 115 System.arraycopy (os, from, fos, 0, to - from); 116 if (listener == null) 117 listener = new Listener (this); 118 return fos; 119 } else 120 throw new UnknownTypeException (parent); 121 } 122 123 132 public int getChildrenCount (Object node) throws UnknownTypeException { 133 if (node == ROOT) { 134 if (listener == null) 135 listener = new Listener (this); 136 return Integer.MAX_VALUE; 138 } else 141 throw new UnknownTypeException (node); 142 } 143 144 public boolean isLeaf (Object node) throws UnknownTypeException { 145 if (node == ROOT) return false; 146 if (node instanceof String ) return true; 147 throw new UnknownTypeException (node); 148 } 149 150 public void addModelListener (ModelListener l) { 151 listeners.add (l); 152 } 153 154 public void removeModelListener (ModelListener l) { 155 listeners.remove (l); 156 } 157 158 public void fireTreeChanged () { 159 Vector v = (Vector) listeners.clone (); 160 int i, k = v.size (); 161 for (i = 0; i < k; i++) 162 ((ModelListener) v.get (i)).modelChanged (null); 163 } 164 165 166 168 public Object getValueAt (Object node, String columnID) throws 169 UnknownTypeException { 170 if ("use".equals (columnID)) { 171 if (node instanceof String ) 172 return Boolean.valueOf ( 173 isEnabled ((String ) node) 174 ); 175 } 176 throw new UnknownTypeException (node); 177 } 178 179 public boolean isReadOnly (Object node, String columnID) throws 180 UnknownTypeException { 181 if ( "use".equals (columnID) && 182 (node instanceof String )) 183 return false; 184 throw new UnknownTypeException (node); 185 } 186 187 public void setValueAt (Object node, String columnID, Object value) 188 throws UnknownTypeException { 189 if ("use".equals (columnID)) { 190 if (node instanceof String ) { 191 setEnabled ((String ) node, ((Boolean ) value).booleanValue ()); 192 return; 193 } 194 } 195 throw new UnknownTypeException (node); 196 } 197 198 199 201 public Action [] getActions (Object node) throws UnknownTypeException { 202 if (node instanceof String ) { 203 if (((String ) node).startsWith (DISP_FILTER_PREFIX)) 204 return new Action [] { 205 NEW_FILTER_ACTION, 206 DELETE_ACTION 207 }; 208 else 209 return new Action [] { 210 NEW_FILTER_ACTION 211 }; 212 } else 213 throw new UnknownTypeException (node); 214 } 215 216 public void performDefaultAction (Object node) 217 throws UnknownTypeException { 218 if (node instanceof String ) { 219 return; 220 } else 221 throw new UnknownTypeException (node); 222 } 223 224 226 private boolean isEnabled (String root) { 227 if (root.startsWith (DISP_FILTER_PREFIX)) { 228 return enabledFilters.contains (root.substring ( 229 DISP_FILTER_PREFIX.length () 230 )); 231 } 232 String [] sourceRoots = sourcePath.getSourceRoots (); 233 int i, k = sourceRoots.length; 234 for (i = 0; i < k; i++) 235 if (sourceRoots [i].equals (root)) return true; 236 return false; 237 } 238 239 private void setEnabled (String root, boolean enabled) { 240 if (root.startsWith (DISP_FILTER_PREFIX)) { 241 String filter = root.substring (DISP_FILTER_PREFIX.length ()); 242 if (enabled) { 243 enabledFilters.add (filter); 244 debugger.getSmartSteppingFilter ().addExclusionPatterns ( 245 Collections.singleton (filter) 246 ); 247 } else { 248 enabledFilters.remove (filter); 249 debugger.getSmartSteppingFilter ().removeExclusionPatterns ( 250 Collections.singleton (filter) 251 ); 252 } 253 saveFilters (); 254 return; 255 } else { 256 Set sourceRoots = new HashSet (Arrays.asList ( 257 sourcePath.getSourceRoots () 258 )); 259 if (enabled) { 260 enabledSourceRoots.add (root); 261 disabledSourceRoots.remove (root); 262 sourceRoots.add (root); 263 } else { 264 disabledSourceRoots.add (root); 265 enabledSourceRoots.remove (root); 266 sourceRoots.remove (root); 267 } 268 String [] ss = new String [sourceRoots.size ()]; 269 sourcePath.setSourceRoots ((String []) sourceRoots.toArray (ss)); 270 saveFilters (); 271 } 272 } 273 274 private void loadFilters () { 275 filters = new HashSet ( 276 filterProperties.getProperties ("class_filters").getCollection ( 277 "all", 278 Collections.EMPTY_SET 279 ) 280 ); 281 enabledFilters = new HashSet ( 282 filterProperties.getProperties ("class_filters").getCollection ( 283 "enabled", 284 Collections.EMPTY_SET 285 ) 286 ); 287 enabledSourceRoots = new HashSet ( 288 filterProperties.getProperties ("source_roots").getCollection ( 289 "enabled", 290 Collections.EMPTY_SET 291 ) 292 ); 293 disabledSourceRoots = new HashSet ( 294 filterProperties.getProperties ("source_roots").getCollection ( 295 "disabled", 296 Collections.EMPTY_SET 297 ) 298 ); 299 } 300 301 private void saveFilters () { 302 filterProperties.getProperties ("class_filters"). 303 setCollection ("all", filters); 304 filterProperties.getProperties ("class_filters"). 305 setCollection ("enabled", enabledFilters); 306 filterProperties.getProperties ("source_roots").setCollection 307 ("enabled", enabledSourceRoots); 308 filterProperties.getProperties ("source_roots").setCollection 309 ("disabled", disabledSourceRoots); 310 } 311 312 313 315 319 public static class DefaultSourcesColumn extends AbstractColumn { 320 321 326 public String getID () { 327 return "DefaultSourcesColumn"; 328 } 329 330 335 public String getDisplayName () { 336 return NbBundle.getBundle (DefaultSourcesColumn.class). 337 getString ("CTL_SourcesModel_Column_Name_Name"); 338 } 339 340 public Character getDisplayedMnemonic() { 341 return new Character (NbBundle.getBundle(SourcesModel.class).getString 342 ("CTL_SourcesModel_Column_Name_Name_Mnc").charAt(0)); 343 } 344 345 350 public String getShortDescription () { 351 return NbBundle.getBundle (DefaultSourcesColumn.class).getString 352 ("CTL_SourcesModel_Column_Name_Desc"); 353 } 354 355 360 public Class getType () { 361 return null; 362 } 363 } 364 365 369 public static class SourcesUsedColumn extends AbstractColumn { 370 371 376 public String getID () { 377 return "use"; 378 } 379 380 385 public String getDisplayName () { 386 return NbBundle.getBundle (SourcesModel.class).getString 387 ("CTL_SourcesModel_Column_Debugging_Name"); 388 } 389 390 public Character getDisplayedMnemonic() { 391 return new Character (NbBundle.getBundle(SourcesModel.class).getString 392 ("CTL_SourcesModel_Column_Debugging_Name_Mnc").charAt(0)); 393 } 394 395 400 public Class getType () { 401 return Boolean.TYPE; 402 } 403 404 410 public String getShortDescription () { 411 return NbBundle.getBundle (SourcesModel.class).getString 412 ("CTL_SourcesModel_Column_Debugging_Desc"); 413 } 414 415 421 public boolean initiallyVisible () { 422 return true; 423 } 424 } 425 426 private final Action NEW_FILTER_ACTION = new AbstractAction 427 (NbBundle.getBundle (SourcesModel.class).getString 428 ("CTL_SourcesModel_Action_AddFilter")) { 429 public void actionPerformed (ActionEvent e) { 430 NotifyDescriptor.InputLine descriptor = new 431 NotifyDescriptor.InputLine ( 432 NbBundle.getBundle (SourcesModel.class).getString 433 ("CTL_SourcesModel_NewFilter_Filter_Label"), 434 NbBundle.getBundle (SourcesModel.class).getString 435 ("CTL_SourcesModel_NewFilter_Title") 436 ); 437 if (DialogDisplayer.getDefault ().notify (descriptor) == 438 NotifyDescriptor.OK_OPTION 439 ) { 440 String filter = descriptor.getInputText (); 441 filters.add (filter); 442 enabledFilters.add (filter); 443 debugger.getSmartSteppingFilter ().addExclusionPatterns ( 444 Collections.singleton (filter) 445 ); 446 saveFilters(); 447 fireTreeChanged (); 448 } 449 } 450 }; 451 private final Action DELETE_ACTION = Models.createAction ( 452 NbBundle.getBundle (SourcesModel.class).getString 453 ("CTL_SourcesModel_Action_Delete"), 454 new Models.ActionPerformer () { 455 public boolean isEnabled (Object node) { 456 return true; 457 } 458 public void perform (Object [] nodes) { 459 int i, k = nodes.length; 460 for (i = 0; i < k; i++) { 461 filters.remove ( 462 ((String ) nodes [i]).substring ( 463 DISP_FILTER_PREFIX.length () 464 ) 465 ); 466 enabledFilters.remove ( 467 ((String ) nodes [i]).substring ( 468 DISP_FILTER_PREFIX.length () 469 ) 470 ); 471 } 472 saveFilters (); 473 fireTreeChanged (); 474 } 475 }, 476 Models.MULTISELECTION_TYPE_ANY 477 ); 478 479 private static class Listener implements PropertyChangeListener { 480 481 private WeakReference model; 482 483 private Listener ( 484 SourcesModel tm 485 ) { 486 model = new WeakReference (tm); 487 tm.sourcePath.addPropertyChangeListener (this); 488 tm.debugger.getSmartSteppingFilter (). 489 addPropertyChangeListener (this); 490 } 491 492 private SourcesModel getModel () { 493 SourcesModel tm = (SourcesModel) model.get (); 494 if (tm == null) { 495 tm.sourcePath.removePropertyChangeListener (this); 496 tm.debugger.getSmartSteppingFilter (). 497 removePropertyChangeListener (this); 498 } 499 return tm; 500 } 501 502 public void propertyChange (PropertyChangeEvent evt) { 503 SourcesModel m = getModel (); 504 if (m == null) return; 505 m.fireTreeChanged (); 506 } 507 } 508 509 513 public abstract static class AbstractColumn extends ColumnModel { 514 515 Properties properties = Properties.getDefault (). 516 getProperties ("debugger").getProperties ("views"); 517 518 519 524 public void setVisible (boolean visible) { 525 properties.setBoolean (getID () + ".visible", visible); 526 } 527 528 533 public void setSorted (boolean sorted) { 534 properties.setBoolean (getID () + ".sorted", sorted); 535 } 536 537 543 public void setSortedDescending (boolean sortedDescending) { 544 properties.setBoolean (getID () + ".sortedDescending", sortedDescending); 545 } 546 547 552 public int getCurrentOrderNumber () { 553 return properties.getInt (getID () + ".currentOrderNumber", -1); 554 } 555 556 561 public void setCurrentOrderNumber (int newOrderNumber) { 562 properties.setInt (getID () + ".currentOrderNumber", newOrderNumber); 563 } 564 565 570 public int getColumnWidth () { 571 return properties.getInt (getID () + ".columnWidth", 150); 572 } 573 574 579 public void setColumnWidth (int newColumnWidth) { 580 properties.setInt (getID () + ".columnWidth", newColumnWidth); 581 } 582 583 588 public boolean isVisible () { 589 return properties.getBoolean (getID () + ".visible", true); 590 } 591 592 597 public boolean isSorted () { 598 return properties.getBoolean (getID () + ".sorted", false); 599 } 600 601 606 public boolean isSortedDescending () { 607 return properties.getBoolean (getID () + ".sortedDescending", false); 608 } 609 } 610 } 611 | Popular Tags |