KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > debugger > jpda > ui > models > SourcesModel


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.debugger.jpda.ui.models;
21
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.beans.PropertyChangeEvent JavaDoc;
24 import java.beans.PropertyChangeListener JavaDoc;
25 import java.lang.ref.WeakReference JavaDoc;
26 import java.util.*;
27 import javax.swing.AbstractAction JavaDoc;
28 import javax.swing.Action JavaDoc;
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 /**
48  * @author Jan Jancura
49  */

50 public class SourcesModel implements TreeModel, TableModel,
51 NodeActionsProvider {
52     
53     private static final String JavaDoc FILTER_PREFIX = "Do not stop in: ";
54     private static final String JavaDoc DISP_FILTER_PREFIX = NbBundle.getBundle
55         (SourcesModel.class).getString ("CTL_SourcesModel_Name_DoNotStopIn");
56     
57     
58     private Listener JavaDoc listener;
59     private SourcePath sourcePath;
60     private JPDADebugger debugger;
61     private Vector listeners = new Vector ();
62     // set of filters
63
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     // TreeModel ...............................................................
81

82     /**
83      *
84      * @return threads contained in this group of threads
85      */

86     public Object JavaDoc getRoot () {
87         return ROOT;
88     }
89     
90     /**
91      *
92      * @return threads contained in this group of threads
93      */

94     public Object JavaDoc[] getChildren (Object JavaDoc parent, int from, int to)
95     throws UnknownTypeException {
96         if (parent == ROOT) {
97             // 1) get source roots
98
String JavaDoc[] sourceRoots = sourcePath.getOriginalSourceRoots ();
99             
100             // 2) get filters
101
String JavaDoc[] ep = new String JavaDoc [filters.size ()];
102             ep = (String JavaDoc[]) 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             // 3) join them
109
Object JavaDoc[] os = new Object JavaDoc [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 JavaDoc[] fos = new Object JavaDoc [to - from];
115             System.arraycopy (os, from, fos, 0, to - from);
116             if (listener == null)
117                 listener = new Listener JavaDoc (this);
118             return fos;
119         } else
120         throw new UnknownTypeException (parent);
121     }
122     
123     /**
124      * Returns number of children for given node.
125      *
126      * @param node the parent node
127      * @throws UnknownTypeException if this TreeModel implementation is not
128      * able to resolve children for given node type
129      *
130      * @return true if node is leaf
131      */

132     public int getChildrenCount (Object JavaDoc node) throws UnknownTypeException {
133         if (node == ROOT) {
134             if (listener == null)
135                 listener = new Listener JavaDoc (this);
136             // Performance, see issue #59058.
137
return Integer.MAX_VALUE;
138             //return sourcePath.getOriginalSourceRoots ().length +
139
// filters.size ();
140
} else
141         throw new UnknownTypeException (node);
142     }
143     
144     public boolean isLeaf (Object JavaDoc node) throws UnknownTypeException {
145         if (node == ROOT) return false;
146         if (node instanceof String JavaDoc) 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     // TableModel ..............................................................
167

168     public Object JavaDoc getValueAt (Object JavaDoc node, String JavaDoc columnID) throws
169     UnknownTypeException {
170         if ("use".equals (columnID)) {
171             if (node instanceof String JavaDoc)
172                 return Boolean.valueOf (
173                     isEnabled ((String JavaDoc) node)
174                 );
175         }
176         throw new UnknownTypeException (node);
177     }
178     
179     public boolean isReadOnly (Object JavaDoc node, String JavaDoc columnID) throws
180     UnknownTypeException {
181         if ( "use".equals (columnID) &&
182              (node instanceof String JavaDoc))
183             return false;
184         throw new UnknownTypeException (node);
185     }
186     
187     public void setValueAt (Object JavaDoc node, String JavaDoc columnID, Object JavaDoc value)
188     throws UnknownTypeException {
189         if ("use".equals (columnID)) {
190             if (node instanceof String JavaDoc) {
191                 setEnabled ((String JavaDoc) node, ((Boolean JavaDoc) value).booleanValue ());
192                 return;
193             }
194         }
195         throw new UnknownTypeException (node);
196     }
197     
198     
199     // NodeActionsProvider .....................................................
200

201     public Action JavaDoc[] getActions (Object JavaDoc node) throws UnknownTypeException {
202         if (node instanceof String JavaDoc) {
203             if (((String JavaDoc) node).startsWith (DISP_FILTER_PREFIX))
204                 return new Action JavaDoc[] {
205                     NEW_FILTER_ACTION,
206                     DELETE_ACTION
207                 };
208             else
209                 return new Action JavaDoc[] {
210                     NEW_FILTER_ACTION
211                 };
212         } else
213         throw new UnknownTypeException (node);
214     }
215     
216     public void performDefaultAction (Object JavaDoc node)
217     throws UnknownTypeException {
218         if (node instanceof String JavaDoc) {
219             return;
220         } else
221         throw new UnknownTypeException (node);
222     }
223     
224     // other methods ...........................................................
225

226     private boolean isEnabled (String JavaDoc root) {
227         if (root.startsWith (DISP_FILTER_PREFIX)) {
228             return enabledFilters.contains (root.substring (
229                 DISP_FILTER_PREFIX.length ()
230             ));
231         }
232         String JavaDoc[] 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 JavaDoc root, boolean enabled) {
240         if (root.startsWith (DISP_FILTER_PREFIX)) {
241             String JavaDoc 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 JavaDoc[] ss = new String JavaDoc [sourceRoots.size ()];
269             sourcePath.setSourceRoots ((String JavaDoc[]) 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     // innerclasses ............................................................
314

315     /**
316      * Defines model for one table view column. Can be used together with
317      * {@link org.netbeans.spi.viewmodel.TreeModel} for tree table view representation.
318      */

319     public static class DefaultSourcesColumn extends AbstractColumn {
320
321         /**
322          * Returns unique ID of this column.
323          *
324          * @return unique ID of this column
325          */

326         public String JavaDoc getID () {
327             return "DefaultSourcesColumn";
328         }
329
330         /**
331          * Returns display name of this column.
332          *
333          * @return display name of this column
334          */

335         public String JavaDoc getDisplayName () {
336             return NbBundle.getBundle (DefaultSourcesColumn.class).
337                 getString ("CTL_SourcesModel_Column_Name_Name");
338         }
339
340         public Character JavaDoc getDisplayedMnemonic() {
341             return new Character JavaDoc(NbBundle.getBundle(SourcesModel.class).getString
342                 ("CTL_SourcesModel_Column_Name_Name_Mnc").charAt(0));
343         }
344
345         /**
346          * Returns tooltip for given column.
347          *
348          * @return tooltip for given node
349          */

350         public String JavaDoc getShortDescription () {
351             return NbBundle.getBundle (DefaultSourcesColumn.class).getString
352                 ("CTL_SourcesModel_Column_Name_Desc");
353         }
354
355         /**
356          * Returns type of column items.
357          *
358          * @return type of column items
359          */

360         public Class JavaDoc getType () {
361             return null;
362         }
363     }
364     
365     /**
366      * Defines model for one table view column. Can be used together with
367      * {@link org.netbeans.spi.viewmodel.TreeModel} for tree table view representation.
368      */

369     public static class SourcesUsedColumn extends AbstractColumn {
370
371         /**
372          * Returns unique ID of this column.
373          *
374          * @return unique ID of this column
375          */

376         public String JavaDoc getID () {
377             return "use";
378         }
379
380         /**
381          * Returns display name of this column.
382          *
383          * @return display name of this column
384          */

385         public String JavaDoc getDisplayName () {
386             return NbBundle.getBundle (SourcesModel.class).getString
387                 ("CTL_SourcesModel_Column_Debugging_Name");
388         }
389
390         public Character JavaDoc getDisplayedMnemonic() {
391             return new Character JavaDoc(NbBundle.getBundle(SourcesModel.class).getString
392                 ("CTL_SourcesModel_Column_Debugging_Name_Mnc").charAt(0));
393         }
394
395         /**
396          * Returns type of column items.
397          *
398          * @return type of column items
399          */

400         public Class JavaDoc getType () {
401             return Boolean.TYPE;
402         }
403
404         /**
405          * Returns tooltip for given column. Default implementation returns
406          * <code>null</code> - do not use tooltip.
407          *
408          * @return tooltip for given node or <code>null</code>
409          */

410         public String JavaDoc getShortDescription () {
411             return NbBundle.getBundle (SourcesModel.class).getString
412                 ("CTL_SourcesModel_Column_Debugging_Desc");
413         }
414
415         /**
416          * True if column should be visible by default. Default implementation
417          * returns <code>true</code>.
418          *
419          * @return <code>true</code> if column should be visible by default
420          */

421         public boolean initiallyVisible () {
422             return true;
423         }
424     }
425     
426     private final Action JavaDoc NEW_FILTER_ACTION = new AbstractAction JavaDoc
427         (NbBundle.getBundle (SourcesModel.class).getString
428             ("CTL_SourcesModel_Action_AddFilter")) {
429             public void actionPerformed (ActionEvent JavaDoc 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 JavaDoc 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 JavaDoc DELETE_ACTION = Models.createAction (
452         NbBundle.getBundle (SourcesModel.class).getString
453             ("CTL_SourcesModel_Action_Delete"),
454         new Models.ActionPerformer () {
455             public boolean isEnabled (Object JavaDoc node) {
456                 return true;
457             }
458             public void perform (Object JavaDoc[] nodes) {
459                 int i, k = nodes.length;
460                 for (i = 0; i < k; i++) {
461                     filters.remove (
462                         ((String JavaDoc) nodes [i]).substring (
463                             DISP_FILTER_PREFIX.length ()
464                         )
465                     );
466                     enabledFilters.remove (
467                         ((String JavaDoc) 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 JavaDoc {
480         
481         private WeakReference JavaDoc model;
482         
483         private Listener (
484             SourcesModel tm
485         ) {
486             model = new WeakReference JavaDoc (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 JavaDoc evt) {
503             SourcesModel m = getModel ();
504             if (m == null) return;
505             m.fireTreeChanged ();
506         }
507     }
508     
509     /**
510      * Defines model for one table view column. Can be used together with
511      * {@link org.netbeans.spi.viewmodel.TreeModel} for tree table view representation.
512      */

513     public abstract static class AbstractColumn extends ColumnModel {
514         
515         Properties properties = Properties.getDefault ().
516             getProperties ("debugger").getProperties ("views");
517
518         
519         /**
520          * Set true if column is visible.
521          *
522          * @param visible set true if column is visible
523          */

524         public void setVisible (boolean visible) {
525             properties.setBoolean (getID () + ".visible", visible);
526         }
527
528         /**
529          * Set true if column should be sorted by default.
530          *
531          * @param sorted set true if column should be sorted by default
532          */

533         public void setSorted (boolean sorted) {
534             properties.setBoolean (getID () + ".sorted", sorted);
535         }
536
537         /**
538          * Set true if column should be sorted by default in descending order.
539          *
540          * @param sortedDescending set true if column should be sorted by default
541          * in descending order
542          */

543         public void setSortedDescending (boolean sortedDescending) {
544             properties.setBoolean (getID () + ".sortedDescending", sortedDescending);
545         }
546     
547         /**
548          * Should return current order number of this column.
549          *
550          * @return current order number of this column
551          */

552         public int getCurrentOrderNumber () {
553             return properties.getInt (getID () + ".currentOrderNumber", -1);
554         }
555
556         /**
557          * Is called when current order number of this column is changed.
558          *
559          * @param newOrderNumber new order number
560          */

561         public void setCurrentOrderNumber (int newOrderNumber) {
562             properties.setInt (getID () + ".currentOrderNumber", newOrderNumber);
563         }
564
565         /**
566          * Return column width of this column.
567          *
568          * @return column width of this column
569          */

570         public int getColumnWidth () {
571             return properties.getInt (getID () + ".columnWidth", 150);
572         }
573
574         /**
575          * Is called when column width of this column is changed.
576          *
577          * @param newColumnWidth a new column width
578          */

579         public void setColumnWidth (int newColumnWidth) {
580             properties.setInt (getID () + ".columnWidth", newColumnWidth);
581         }
582
583         /**
584          * True if column should be visible by default.
585          *
586          * @return true if column should be visible by default
587          */

588         public boolean isVisible () {
589             return properties.getBoolean (getID () + ".visible", true);
590         }
591
592         /**
593          * True if column should be sorted by default.
594          *
595          * @return true if column should be sorted by default
596          */

597         public boolean isSorted () {
598             return properties.getBoolean (getID () + ".sorted", false);
599         }
600
601         /**
602          * True if column should be sorted by default in descending order.
603          *
604          * @return true if column should be sorted by default in descending order
605          */

606         public boolean isSortedDescending () {
607             return properties.getBoolean (getID () + ".sortedDescending", false);
608         }
609     }
610 }
611
Popular Tags