KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > debug > callstackviewfilterring > CallStackFilter


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.j2ee.debug.callstackviewfilterring;
21
22 import com.sun.jdi.AbsentInformationException;
23 import org.netbeans.api.debugger.jpda.CallStackFrame;
24 import org.netbeans.api.debugger.jpda.JPDADebugger;
25 import org.netbeans.spi.debugger.ContextProvider;
26 import org.netbeans.spi.debugger.jpda.SourcePathProvider;
27 import org.netbeans.spi.viewmodel.NodeModel;
28 import org.netbeans.spi.viewmodel.TableModel;
29 import org.netbeans.spi.viewmodel.TableModelFilter;
30 import org.netbeans.spi.viewmodel.TreeModel;
31 import org.netbeans.spi.viewmodel.TreeModelFilter;
32 import org.netbeans.spi.viewmodel.ModelListener;
33 import org.netbeans.spi.viewmodel.UnknownTypeException;
34 import org.openide.util.NbBundle;
35
36 import java.beans.PropertyChangeListener JavaDoc;
37 import java.io.File JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.List JavaDoc;
40
41 /**
42  *
43  * @author Libor Kotouc
44  */

45 public class CallStackFilter implements TreeModelFilter, NodeModel, TableModelFilter {
46     
47     private ContextProvider lookupProvider;
48     private JPDADebugger debugger;
49     private SourcePathProvider contextProvider;
50    
51     public CallStackFilter (ContextProvider lookupProvider) {
52         this.lookupProvider = lookupProvider;
53         debugger = (JPDADebugger) lookupProvider.
54             lookupFirst(null, JPDADebugger.class);
55     }
56
57     private static String JavaDoc convertSlash (String JavaDoc original) {
58         return original.replace (File.separatorChar, '/');
59     }
60
61     private static String JavaDoc convertClassNameToRelativePath (
62             String JavaDoc className
63         ) {
64         int i = className.indexOf ('$');
65         if (i > 0) className = className.substring (0, i);
66         String JavaDoc sourceName = className.replace('.', '/') + ".java";
67         return sourceName;
68     }
69
70     private SourcePathProvider getSourcePathProvider() {
71         if (contextProvider == null) {
72             List JavaDoc l = lookupProvider.lookup (null, SourcePathProvider.class);
73             contextProvider = (SourcePathProvider) l.get (0);
74             int i, k = l.size ();
75             for (i = 1; i < k; i++) {
76                 contextProvider = new CompoundSourcePathProvider (
77                     (SourcePathProvider) l.get (i),
78                     contextProvider
79                 );
80             }
81         }
82         return contextProvider;
83     }
84
85     /**
86      * Translates a relative path ("java/lang/Thread.java") to url
87      * ("file:///C:/Sources/java/lang/Thread.java"). Uses GlobalPathRegistry
88      * if global == true.
89      *
90      * @param relativePath a relative path (java/lang/Thread.java)
91      * @param global true if global path should be used
92      * @return url
93      */

94     String JavaDoc getURL(String JavaDoc relativePath) {
95         return getSourcePathProvider().getURL (relativePath, false);
96     }
97
98     boolean isOnSourcePath(CallStackFrame csf) {
99         
100         String JavaDoc url = null;
101         
102         try {
103             url = getURL (convertSlash (csf.getSourcePath (null)));
104         } catch (AbsentInformationException e) {
105             url = getURL (convertClassNameToRelativePath (csf.getClassName ()));
106         }
107         
108         return url != null;
109     }
110
111     
112     
113     
114     /**
115      * Returns filtered root of hierarchy.
116      *
117      * @param original the original tree model
118      * @return filtered root of hierarchy
119      */

120     public Object JavaDoc getRoot (TreeModel original) {
121         return original.getRoot ();
122     }
123     
124     /**
125      * Returns number of filterred children for given node.
126      *
127      * @param original the original tree model
128      * @param node the parent node
129      * @throws NoInformationException if the set of children can not be
130      * resolved
131      * @throws ComputingException if the children resolving process
132      * is time consuming, and will be performed off-line
133      * @throws UnknownTypeException if this TreeModel implementation is not
134      * able to resolve children for given node type
135      *
136      * @return true if node is leaf
137      */

138     public int getChildrenCount (
139         TreeModel original,
140         Object JavaDoc node
141     ) throws UnknownTypeException {
142         if (node.equals (original.getRoot ())) {
143             Object JavaDoc[] originalCh = original.getChildren (
144                 node,
145                 0,
146                 original.getChildrenCount (node)
147             );
148             int i, k = originalCh.length, j = 0;
149             boolean in = false;
150             for (i = 0; i < k; i++) {
151                 if (! (originalCh [i] instanceof CallStackFrame)) {
152                     j++;
153                     continue;
154                 }
155                 CallStackFrame f = (CallStackFrame) originalCh [i];
156                 if (!isOnSourcePath(f)) {
157                     if (!in) {
158                         j++;
159                         in = true;
160                     }
161                 } else {
162                     in = false;
163                     j++;
164                 }
165             }
166             return j;
167         }
168         if (node instanceof HiddenFrames)
169             return ((HiddenFrames) node).getStack ().size ();
170         return original.getChildrenCount (node);
171     }
172     
173     /**
174      * Returns filtered children for given parent on given indexes.
175      * Typically you should get original nodes
176      * (<code>original.getChildren (...)</code>), and modify them, or return
177      * it without modifications. You should not throw UnknownTypeException
178      * directly from this method!
179      *
180      * @param original the original tree model
181      * @param parent a parent of returned nodes
182      * @throws NoInformationException if the set of children can not be
183      * resolved
184      * @throws ComputingException if the children resolving process
185      * is time consuming, and will be performed off-line
186      * @throws UnknownTypeException this exception can be thrown from
187      * <code>original.getChildren (...)</code> method call only!
188      *
189      * @return children for given parent on given indexes
190      */

191     public Object JavaDoc[] getChildren (
192         TreeModel original,
193         Object JavaDoc parent,
194         int from,
195         int to
196     ) throws UnknownTypeException {
197         if (parent.equals (original.getRoot ())) {
198             Object JavaDoc[] originalCh = original.getChildren (
199                 parent,
200                 0,
201                 original.getChildrenCount (parent)
202             );
203             int i, k = originalCh.length;
204             ArrayList JavaDoc newCh = new ArrayList JavaDoc ();
205             HiddenFrames hiddenFrames = null;
206             for (i = 0; i < k; i++) {
207                 if (! (originalCh [i] instanceof CallStackFrame)) {
208                     newCh.add (originalCh [i]);
209                     continue;
210                 }
211                 CallStackFrame f = (CallStackFrame) originalCh [i];
212                 if (!isOnSourcePath(f)) {
213                     if (hiddenFrames == null) {
214                         hiddenFrames = new HiddenFrames ();
215                         newCh.add (hiddenFrames);
216                     }
217                     hiddenFrames.addFrame (f);
218                 } else {
219                     hiddenFrames = null;
220                     newCh.add (f);
221                 }
222             }
223             //Fix issue #53878: 'to' returned from original in getChildrenCount()
224
//is higher than number of children got from getChildren() in this method.
225
//It is random JPDA debugger's bug.
226
int lto = Math.min(newCh.size(), to);
227             return newCh.subList (from, lto).toArray ();
228         }
229         if (parent instanceof HiddenFrames)
230             return ((HiddenFrames) parent).getStack ().toArray ();
231         return original.getChildren (parent, from, to);
232     }
233     
234     /**
235      * Returns true if node is leaf. You should not throw UnknownTypeException
236      * directly from this method!
237      *
238      * @param original the original tree model
239      * @throws UnknownTypeException this exception can be thrown from
240      * <code>original.isLeaf (...)</code> method call only!
241      * @return true if node is leaf
242      */

243     public boolean isLeaf (TreeModel original, Object JavaDoc node)
244     throws UnknownTypeException {
245         if (node instanceof HiddenFrames) return false;
246         return original.isLeaf (node);
247     }
248     
249     public void addModelListener (ModelListener l) {
250     }
251     public void removeModelListener (ModelListener l) {
252     }
253     
254     public String JavaDoc getDisplayName (Object JavaDoc node) throws UnknownTypeException {
255         if (node instanceof HiddenFrames)
256             return NbBundle.getMessage(CallStackFilter.class, "LBL_HIDDEN_FRAMES");
257         throw new UnknownTypeException (node);
258     }
259     
260     public String JavaDoc getIconBase (Object JavaDoc node) throws UnknownTypeException {
261         if (node instanceof HiddenFrames)
262             return NbBundle.getMessage(CallStackFilter.class, "RES_FRAME_GROUP");
263         throw new UnknownTypeException (node);
264     }
265     
266     public String JavaDoc getShortDescription (Object JavaDoc node) throws UnknownTypeException {
267         if (node instanceof HiddenFrames)
268             return NbBundle.getMessage(CallStackFilter.class, "TLT_HIDDEN_FRAMES");
269         throw new UnknownTypeException (node);
270     }
271
272     //----------------------- TableModelFilter implementation ----------------------------
273

274     public void setValueAt(TableModel original, Object JavaDoc node, String JavaDoc columnID, Object JavaDoc value) throws UnknownTypeException {
275         
276         original.setValueAt(node, columnID, value);
277     }
278
279     public boolean isReadOnly(TableModel original, Object JavaDoc node, String JavaDoc columnID) throws UnknownTypeException {
280         
281         if (node instanceof HiddenFrames)
282             return true;
283         
284         return original.isReadOnly(node, columnID);
285     }
286
287     public Object JavaDoc getValueAt(TableModel original, Object JavaDoc node, String JavaDoc columnID) throws UnknownTypeException {
288         
289         if (node instanceof HiddenFrames)
290             return "";
291         
292         return original.getValueAt(node, columnID);
293     }
294     
295     
296     // innerclasses ............................................................
297

298     public static class HiddenFrames {
299         private List JavaDoc frames = new ArrayList JavaDoc ();
300         
301         void addFrame (CallStackFrame frame) {
302             frames.add (frame);
303         }
304         
305         List JavaDoc getStack () {
306             return frames;
307         }
308         
309         public boolean equals (Object JavaDoc o) {
310             if (!(o instanceof HiddenFrames)) return false;
311             if (frames.size () != ((HiddenFrames) o).frames.size ()) return false;
312             if (frames.size () == 0) return o == this;
313             return frames.get (0).equals (
314                 ((HiddenFrames) o).frames.get (0)
315             );
316         }
317         
318         public int hashCode () {
319             if (frames.size () == 0) return super.hashCode ();
320             return frames.get (0).hashCode ();
321         }
322     }
323
324     private static class CompoundSourcePathProvider extends SourcePathProvider {
325
326         private SourcePathProvider cp1, cp2;
327
328         CompoundSourcePathProvider (
329             SourcePathProvider cp1,
330             SourcePathProvider cp2
331         ) {
332             this.cp1 = cp1;
333             this.cp2 = cp2;
334         }
335
336         public String JavaDoc getURL (String JavaDoc relativePath, boolean global) {
337             String JavaDoc p1 = cp1.getURL (relativePath, global);
338             if (p1 != null) return p1;
339             return cp2.getURL (relativePath, global);
340         }
341
342         public String JavaDoc getRelativePath (
343             String JavaDoc url,
344             char directorySeparator,
345             boolean includeExtension
346         ) {
347             String JavaDoc p1 = cp1.getRelativePath (
348                 url,
349                 directorySeparator,
350                 includeExtension
351             );
352             if (p1 != null) return p1;
353             return cp2.getRelativePath (
354                 url,
355                 directorySeparator,
356                 includeExtension
357             );
358         }
359     
360         public String JavaDoc[] getSourceRoots () {
361             String JavaDoc[] fs1 = cp1.getSourceRoots ();
362             String JavaDoc[] fs2 = cp2.getSourceRoots ();
363             String JavaDoc[] fs = new String JavaDoc [fs1.length + fs2.length];
364             System.arraycopy (fs1, 0, fs, 0, fs1.length);
365             System.arraycopy (fs2, 0, fs, fs1.length, fs2.length);
366             return fs;
367         }
368     
369         public String JavaDoc[] getOriginalSourceRoots () {
370             String JavaDoc[] fs1 = cp1.getOriginalSourceRoots ();
371             String JavaDoc[] fs2 = cp2.getOriginalSourceRoots ();
372             String JavaDoc[] fs = new String JavaDoc [fs1.length + fs2.length];
373             System.arraycopy (fs1, 0, fs, 0, fs1.length);
374             System.arraycopy (fs2, 0, fs, fs1.length, fs2.length);
375             return fs;
376         }
377
378         public void setSourceRoots (String JavaDoc[] sourceRoots) {
379             cp1.setSourceRoots (sourceRoots);
380             cp2.setSourceRoots (sourceRoots);
381         }
382
383         public void addPropertyChangeListener (PropertyChangeListener JavaDoc l) {
384             cp1.addPropertyChangeListener (l);
385             cp2.addPropertyChangeListener (l);
386         }
387
388         public void removePropertyChangeListener (PropertyChangeListener JavaDoc l) {
389             cp1.removePropertyChangeListener (l);
390             cp2.removePropertyChangeListener (l);
391         }
392     }
393
394 }
395
Popular Tags