KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > debugger > jpda > ui > SourcePath


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 Micro//S ystems, Inc. Portions Copyright 1997-2006 Sun
17  * Micro//S ystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.debugger.jpda.ui;
20
21 import com.sun.jdi.AbsentInformationException;
22 import com.sun.jdi.StackFrame;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.io.File JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Arrays JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.WeakHashMap JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Set JavaDoc;
33 import org.netbeans.api.debugger.Properties;
34 import org.netbeans.spi.debugger.ContextProvider;
35
36 import org.netbeans.api.debugger.DebuggerManager;
37 import org.netbeans.api.debugger.Session;
38 import org.netbeans.api.debugger.jpda.CallStackFrame;
39 import org.netbeans.api.debugger.jpda.Field;
40 import org.netbeans.api.debugger.jpda.JPDADebugger;
41 import org.netbeans.api.debugger.jpda.JPDAThread;
42 import org.netbeans.api.debugger.jpda.LineBreakpoint;
43 import org.netbeans.api.debugger.jpda.LocalVariable;
44 import org.netbeans.api.debugger.jpda.Variable;
45 import org.netbeans.spi.debugger.jpda.EditorContext;
46 import org.netbeans.spi.debugger.jpda.EditorContext.Operation;
47 import org.netbeans.spi.debugger.jpda.SourcePathProvider;
48 import org.openide.ErrorManager;
49
50 /**
51  * Utility methods for sources.
52  *
53  * @see Similar class in debuggerjpda when modifying this.
54  *
55  * @author Jan Jancura
56  */

57 public class SourcePath {
58
59     private ContextProvider contextProvider;
60     private SourcePathProvider sourcePathProvider;
61     private JPDADebugger debugger;
62     
63
64     public SourcePath (ContextProvider contextProvider) {
65         this.contextProvider = contextProvider;
66         debugger = (JPDADebugger) contextProvider.lookupFirst
67             (null, JPDADebugger.class);
68     }
69
70     private SourcePathProvider getContext () {
71         if (sourcePathProvider == null) {
72             List JavaDoc l = contextProvider.lookup (null, SourcePathProvider.class);
73             sourcePathProvider = (SourcePathProvider) l.get (0);
74             int i, k = l.size ();
75             for (i = 1; i < k; i++) {
76                 sourcePathProvider = new CompoundContextProvider (
77                     (SourcePathProvider) l.get (i),
78                     sourcePathProvider
79                 );
80             }
81             initSourcePaths ();
82         }
83         return sourcePathProvider;
84     }
85
86     
87     // ContextProvider methods .................................................
88

89     /**
90      * Returns relative path for given url.
91      *
92      * @param url a url of resource file
93      * @param directorySeparator a directory separator character
94      * @param includeExtension whether the file extension should be included
95      * in the result
96      *
97      * @return relative path
98      */

99     public String JavaDoc getRelativePath (
100         String JavaDoc url,
101         char directorySeparator,
102         boolean includeExtension
103     ) {
104         return getContext ().getRelativePath
105             (url, directorySeparator, includeExtension);
106     }
107
108     /**
109      * Translates a relative path ("java/lang/Thread.java") to url
110      * ("file:///C:/Sources/java/lang/Thread.java"). Uses GlobalPathRegistry
111      * if global == true.
112      *
113      * @param relativePath a relative path (java/lang/Thread.java)
114      * @param global true if global path should be used
115      * @return url
116      */

117     public String JavaDoc getURL (String JavaDoc relativePath, boolean global) {
118         return getContext ().getURL (relativePath, global);
119     }
120     
121     public String JavaDoc getURL (
122         StackFrame sf,
123         String JavaDoc stratumn
124     ) {
125         try {
126             return getURL (
127                 convertSlash (sf.location ().sourcePath (stratumn)),
128                 true
129             );
130         } catch (AbsentInformationException e) {
131             return getURL (
132                 convertClassNameToRelativePath (
133                     sf.location ().declaringType ().name ()
134                 ),
135                 true
136             );
137         }
138     }
139     
140     /**
141      * Returns array of source roots.
142      */

143     public String JavaDoc[] getSourceRoots () {
144         return getContext ().getSourceRoots ();
145     }
146     
147     /**
148      * Sets array of source roots.
149      *
150      * @param sourceRoots a new array of sourceRoots
151      */

152     public void setSourceRoots (String JavaDoc[] sourceRoots) {
153         getContext ().setSourceRoots (sourceRoots);
154     }
155     
156     /**
157      * Returns set of original source roots.
158      *
159      * @return set of original source roots
160      */

161     public String JavaDoc[] getOriginalSourceRoots () {
162         return getContext ().getOriginalSourceRoots ();
163     }
164     
165     /**
166      * Adds property change listener.
167      *
168      * @param l new listener.
169      */

170     public void addPropertyChangeListener (PropertyChangeListener JavaDoc l) {
171         getContext ().addPropertyChangeListener (l);
172     }
173
174     /**
175      * Removes property change listener.
176      *
177      * @param l removed listener.
178      */

179     public void removePropertyChangeListener (
180         PropertyChangeListener JavaDoc l
181     ) {
182         getContext ().removePropertyChangeListener (l);
183     }
184     
185     
186     // utility methods .........................................................
187

188     public boolean sourceAvailable (
189         String JavaDoc relativePath,
190         boolean global
191     ) {
192         return getURL (relativePath, global) != null;
193     }
194
195     public boolean sourceAvailable (
196         JPDAThread t,
197         String JavaDoc stratumn,
198         boolean global
199     ) {
200         try {
201             return sourceAvailable (
202                 convertSlash (t.getSourcePath (stratumn)), global
203             );
204         } catch (AbsentInformationException e) {
205             return sourceAvailable (
206                 convertClassNameToRelativePath (t.getClassName ()), global
207             );
208         }
209     }
210
211     public boolean sourceAvailable (
212         Field f
213     ) {
214         String JavaDoc className = f.getClassName ();
215         return sourceAvailable (className, true);
216     }
217
218     public boolean sourceAvailable (
219         CallStackFrame csf,
220         String JavaDoc stratumn
221     ) {
222         try {
223             return sourceAvailable (
224                 convertSlash (csf.getSourcePath (stratumn)), true
225             );
226         } catch (AbsentInformationException e) {
227             return sourceAvailable (
228                 convertClassNameToRelativePath (csf.getClassName ()), true
229             );
230         }
231     }
232
233     public String JavaDoc getURL (
234         CallStackFrame csf,
235         String JavaDoc stratumn
236     ) {
237         try {
238             return getURL (convertSlash (csf.getSourcePath (stratumn)), true);
239         } catch (AbsentInformationException e) {
240             return getURL (
241                 convertClassNameToRelativePath (csf.getClassName ()), true
242             );
243         }
244     }
245
246     public boolean showSource (
247         JPDAThread t,
248         String JavaDoc stratumn
249     ) {
250         int lineNumber = t.getLineNumber (stratumn);
251         if (lineNumber < 1) lineNumber = 1;
252         try {
253             return EditorContextBridge.showSource (
254                 getURL (convertSlash (t.getSourcePath (stratumn)), true),
255                 lineNumber,
256                 debugger
257             );
258         } catch (AbsentInformationException e) {
259             return EditorContextBridge.showSource (
260                 getURL (
261                     convertClassNameToRelativePath (t.getClassName ()), true
262                 ),
263                 lineNumber,
264                 debugger
265             );
266         }
267     }
268
269     public boolean showSource (CallStackFrame csf, String JavaDoc stratumn) {
270         try {
271             String JavaDoc url = getURL (
272                 convertSlash (csf.getSourcePath (stratumn)), true
273             );
274             if (url == null) {
275                 stratumn = csf.getDefaultStratum ();
276                 url = getURL (
277                     convertSlash (csf.getSourcePath (stratumn)), true
278                 );
279             }
280             if (url == null) {
281                 ErrorManager.getDefault().log(ErrorManager.WARNING,
282                         "Show Source: No URL for source path "+csf.getSourcePath (stratumn)+
283                         "\nThe reason is likely no opened project for this source file.");
284                 return false;
285             }
286             int lineNumber = csf.getLineNumber (stratumn);
287             if (lineNumber < 1) lineNumber = 1;
288             return EditorContextBridge.showSource (
289                 url,
290                 lineNumber,
291                 debugger
292             );
293         } catch (AbsentInformationException e) {
294             String JavaDoc url = getURL (
295                 convertClassNameToRelativePath (csf.getClassName ()), true
296             );
297             if (url == null) {
298                 ErrorManager.getDefault().log(ErrorManager.WARNING,
299                         "Show Source: No source URL for class "+csf.getClassName()+
300                         "\nThe reason is likely no opened project for the source file.");
301                 return false;
302             }
303             return EditorContextBridge.showSource (
304                 url,
305                 1,
306                 debugger
307             );
308         }
309     }
310
311     public boolean showSource (Field v) {
312         String JavaDoc fieldName = ((Field) v).getName ();
313         String JavaDoc className = className = ((Field) v).getClassName ();
314         String JavaDoc url = getURL (
315             EditorContextBridge.getRelativePath (className), true
316         );
317         if (url == null) return false;
318         int lineNumber = lineNumber = EditorContextBridge.getFieldLineNumber (
319             url,
320             className,
321             fieldName
322         );
323         if (lineNumber < 1) lineNumber = 1;
324         return EditorContextBridge.showSource (
325             url,
326             lineNumber,
327             debugger
328         );
329     }
330
331     private static String JavaDoc convertSlash (String JavaDoc original) {
332         return original.replace (File.separatorChar, '/');
333     }
334
335     public static String JavaDoc convertClassNameToRelativePath (
336         String JavaDoc className
337     ) {
338         int i = className.indexOf ('$');
339         if (i > 0) className = className.substring (0, i);
340         String JavaDoc sourceName = className.replace
341             ('.', '/') + ".java";
342         return sourceName;
343     }
344
345     public Object JavaDoc annotate (
346         JPDAThread t,
347         String JavaDoc stratumn
348     ) {
349         int lineNumber = t.getLineNumber (stratumn);
350         if (lineNumber < 1) return null;
351         //AST ast = t.getAST(stratumn);
352
Operation operation = t.getCurrentOperation();
353         String JavaDoc url;
354         try {
355             url = getURL (convertSlash (t.getSourcePath (stratumn)), true);
356         } catch (AbsentInformationException e) {
357             url = getURL (convertClassNameToRelativePath (t.getClassName ()), true);
358         }
359         List JavaDoc operationsAnn = annotateOperations(debugger, url, operation, t.getLastOperations(), lineNumber);
360         if (operation == null) {
361             if (operationsAnn.size() == 0) {
362                 return EditorContextBridge.annotate (
363                     url,
364                     lineNumber,
365                     EditorContext.CURRENT_LINE_ANNOTATION_TYPE,
366                     debugger
367                 );
368             } else {
369                 /*
370                 operationsAnn.add(EditorContextBridge.annotate (
371                     url,
372                     lineNumber,
373                     EditorContext.CURRENT_LINE_ANNOTATION_TYPE,
374                     debugger
375                 ));
376                  */

377             }
378         }
379         return operationsAnn;
380     }
381
382     public Object JavaDoc annotate (
383         CallStackFrame csf,
384         String JavaDoc stratumn
385     ) {
386         int lineNumber = csf.getLineNumber (stratumn);
387         if (lineNumber < 1) return null;
388         Operation operation = csf.getCurrentOperation(stratumn);
389         try {
390             if (operation != null) {
391                 int startOffset;
392                 int endOffset;
393                 if (operation.getMethodName() != null) {
394                     startOffset = operation.getMethodStartPosition().getOffset();
395                     endOffset = operation.getMethodEndPosition().getOffset();
396                 } else {
397                     startOffset = operation.getStartPosition().getOffset();
398                     endOffset = operation.getEndPosition().getOffset();
399                 }
400                 return EditorContextBridge.annotate (
401                     getURL (convertSlash (csf.getSourcePath (stratumn)), true),
402                     startOffset,
403                     endOffset,
404                     EditorContext.CALL_STACK_FRAME_ANNOTATION_TYPE,
405                     debugger
406                 );
407             } else {
408                 return EditorContextBridge.annotate (
409                     getURL (convertSlash (csf.getSourcePath (stratumn)), true),
410                     lineNumber,
411                     EditorContext.CALL_STACK_FRAME_ANNOTATION_TYPE,
412                     debugger
413                 );
414             }
415         } catch (AbsentInformationException e) {
416             return EditorContextBridge.annotate (
417                 getURL (
418                     convertClassNameToRelativePath (csf.getClassName ()), true
419                 ),
420                 lineNumber,
421                 EditorContext.CALL_STACK_FRAME_ANNOTATION_TYPE,
422                 debugger
423             );
424         }
425     }
426     
427     private static List JavaDoc annotateOperations(JPDADebugger debugger, String JavaDoc url,
428                                            Operation currentOperation, List JavaDoc lastOperations,
429                                            int locLineNumber) {
430         List JavaDoc annotations = null;
431         if (currentOperation != null) {
432             annotations = new ArrayList JavaDoc();
433             annotations.add(createAnnotation(debugger, url, currentOperation,
434                                              EditorContext.CURRENT_LINE_ANNOTATION_TYPE,
435                                              true));
436             int lineNumber;
437             if (currentOperation.getMethodName() != null) {
438                 lineNumber = currentOperation.getMethodStartPosition().getLine();
439             } else {
440                 lineNumber = currentOperation.getStartPosition().getLine();
441             }
442             annotations.add(EditorContextBridge.annotate (
443                 url,
444                 lineNumber,
445                 EditorContext.CURRENT_EXPRESSION_CURRENT_LINE_ANNOTATION_TYPE,
446                 debugger
447             ));
448         }
449         boolean isNewLineExp = false;
450         if (lastOperations != null && lastOperations.size() > 0) {
451             if (annotations == null) {
452                 annotations = new ArrayList JavaDoc();
453             }
454             isNewLineExp = currentOperation == null;
455             for (int i = 0; i < lastOperations.size(); i++) {
456                 Operation lastOperation = (Operation) lastOperations.get(i);
457                 if (currentOperation == lastOperation && i == lastOperations.size() - 1) {
458                     annotations.add(createAnnotation(debugger, url,
459                                                      lastOperation,
460                                                      EditorContext.CURRENT_OUT_OPERATION_ANNOTATION_TYPE,
461                                                      false));
462                     int lineNumber = lastOperation.getEndPosition().getLine();
463                     annotations.add(EditorContextBridge.annotate (
464                         url,
465                         lineNumber,
466                         EditorContext.CURRENT_EXPRESSION_CURRENT_LINE_ANNOTATION_TYPE,
467                         debugger
468                     ));
469                     isNewLineExp = false;
470                 } else {
471                     annotations.add(createAnnotation(debugger, url,
472                                                      lastOperation,
473                                                      EditorContext.CURRENT_LAST_OPERATION_ANNOTATION_TYPE,
474                                                      true));
475                 }
476             }
477         }
478         if (isNewLineExp) {
479             annotations.add(EditorContextBridge.annotate (
480                 url,
481                 locLineNumber,
482                 EditorContext.CURRENT_LINE_ANNOTATION_TYPE,
483                 debugger
484             ));
485         }
486         if (annotations != null) {
487             return annotations;
488         } else {
489             return Collections.EMPTY_LIST;
490         }
491     }
492     
493     private static Object JavaDoc createAnnotation(JPDADebugger debugger, String JavaDoc url,
494                                            Operation operation, String JavaDoc type,
495                                            boolean method) {
496         int startOffset;
497         int endOffset;
498         if (method && operation.getMethodName() != null) {
499             startOffset = operation.getMethodStartPosition().getOffset();
500             endOffset = operation.getMethodEndPosition().getOffset();
501         } else {
502             startOffset = operation.getStartPosition().getOffset();
503             endOffset = operation.getEndPosition().getOffset();
504         }
505         return EditorContextBridge.annotate (
506             url,
507             startOffset,
508             endOffset,
509             type,
510             debugger
511         );
512     }
513
514     
515     // innerclasses ............................................................
516

517     private static class CompoundContextProvider extends SourcePathProvider {
518
519         private SourcePathProvider cp1, cp2;
520
521         CompoundContextProvider (
522             SourcePathProvider cp1,
523             SourcePathProvider cp2
524         ) {
525             this.cp1 = cp1;
526             this.cp2 = cp2;
527         }
528
529         public String JavaDoc getURL (String JavaDoc relativePath, boolean global) {
530             String JavaDoc p1 = cp1.getURL (relativePath, global);
531             if (p1 != null) return p1;
532             return cp2.getURL (relativePath, global);
533         }
534
535         public String JavaDoc getRelativePath (
536             String JavaDoc url,
537             char directorySeparator,
538             boolean includeExtension
539         ) {
540             String JavaDoc p1 = cp1.getRelativePath (
541                 url,
542                 directorySeparator,
543                 includeExtension
544             );
545             if (p1 != null) return p1;
546             return cp2.getRelativePath (
547                 url,
548                 directorySeparator,
549                 includeExtension
550             );
551         }
552     
553         public String JavaDoc[] getSourceRoots () {
554             String JavaDoc[] fs1 = cp1.getSourceRoots ();
555             String JavaDoc[] fs2 = cp2.getSourceRoots ();
556             String JavaDoc[] fs = new String JavaDoc [fs1.length + fs2.length];
557             System.arraycopy (fs1, 0, fs, 0, fs1.length);
558             System.arraycopy (fs2, 0, fs, fs1.length, fs2.length);
559             return fs;
560         }
561     
562         public String JavaDoc[] getOriginalSourceRoots () {
563             String JavaDoc[] fs1 = cp1.getOriginalSourceRoots ();
564             String JavaDoc[] fs2 = cp2.getOriginalSourceRoots ();
565             String JavaDoc[] fs = new String JavaDoc [fs1.length + fs2.length];
566             System.arraycopy (fs1, 0, fs, 0, fs1.length);
567             System.arraycopy (fs2, 0, fs, fs1.length, fs2.length);
568             return fs;
569         }
570
571         public void setSourceRoots (String JavaDoc[] sourceRoots) {
572             cp1.setSourceRoots (sourceRoots);
573             cp2.setSourceRoots (sourceRoots);
574         }
575
576         public void addPropertyChangeListener (PropertyChangeListener JavaDoc l) {
577             cp1.addPropertyChangeListener (l);
578             cp2.addPropertyChangeListener (l);
579         }
580
581         public void removePropertyChangeListener (PropertyChangeListener JavaDoc l) {
582             cp1.removePropertyChangeListener (l);
583             cp2.removePropertyChangeListener (l);
584         }
585     }
586     
587     private void initSourcePaths () {
588         Properties properties = Properties.getDefault ().
589             getProperties ("debugger").getProperties ("sources");
590         Set JavaDoc originalSourceRoots = new HashSet JavaDoc (Arrays.asList (
591             sourcePathProvider.getOriginalSourceRoots ()
592         ));
593         Set JavaDoc sourceRoots = new HashSet JavaDoc (Arrays.asList (
594             sourcePathProvider.getSourceRoots ()
595         ));
596
597         Iterator JavaDoc enabledSourceRoots = properties.getProperties ("source_roots").
598             getCollection ("enabled", Collections.EMPTY_SET).iterator ();
599         while (enabledSourceRoots.hasNext ()) {
600             String JavaDoc root = (String JavaDoc) enabledSourceRoots.next ();
601             if (originalSourceRoots.contains (root))
602                 sourceRoots.add (root);
603         }
604         Iterator JavaDoc disabledSourceRoots = properties.getProperties ("source_roots").
605             getCollection ("disabled", Collections.EMPTY_SET).iterator ();
606         while (disabledSourceRoots.hasNext ()) {
607             String JavaDoc root = (String JavaDoc) disabledSourceRoots.next ();
608             sourceRoots.remove (root);
609         }
610         String JavaDoc[] ss = new String JavaDoc [sourceRoots.size ()];
611         sourcePathProvider.setSourceRoots ((String JavaDoc[]) sourceRoots.toArray (ss));
612     }
613
614     private static class CompoundAnnotation {
615         Object JavaDoc annotation1;
616         Object JavaDoc annotation2;
617     }
618 }
619
620
Popular Tags