KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > debugger > gui > AJLineMapper


1 /* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the debugger and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  */

22
23 package org.aspectj.debugger.gui;
24
25 import org.aspectj.debugger.base.*;
26
27 import java.io.*;
28 import java.util.*;
29 import java.util.List JavaDoc;
30 import org.aspectj.tools.ide.*;
31 import com.sun.jdi.*;
32
33 public class AJLineMapper {
34
35     /** Put classes that were not compiled with AJC here. */
36     private static HashMap noAJCHash = new HashMap();
37
38     public final static String JavaDoc NO_SOURCE_STRING = "<not-available>";
39     public final static String JavaDoc NON_MAPPING_SOURCE_STRING = "<non-mapping-source>";
40     public final static String JavaDoc UNKNOWN_SOURCE_STRING = "<unknown>";
41     public final static int NO_SOURCE_LINE = -1;
42     public final static int NON_MAPPING_SOURCE_LINE = -2;
43
44     public static SymbolManager symbolManager = new SymbolManager();
45
46     /**
47      * TODO: move to org.aspectj.tools.SourceLine
48      *
49      * @param filePath the full path to the preprocessed source file
50      * @param lineNumber line number in the preprocessed source file
51      * @return true when the method has a corresponding signature in the source code
52      * @return false otherwise
53      */

54     public boolean hasBody() {
55         return true;
56     }
57
58     public static SymbolManager sm() {
59         return symbolManager;
60     }
61
62     public static int getCorrespondingOutputLineNo(String JavaDoc classID, int line) {
63         return AJLineMapper.getCorrespondingOutputLine(classID, line).line;
64     }
65
66     public static SourceLine getCorrespondingOutputLine(String JavaDoc classID, int line) {
67         String JavaDoc filePath = getSourceFilePathFromAJCClass(classID);
68         return getCorrespondingOutputLineFromFullSource(filePath, line);
69     }
70
71     public static SourceLine getCorrespondingOutputLineFromSource(String JavaDoc source,
72                                                                   int line) {
73         String JavaDoc filePath = getFullFileNameFromFile(source, false);
74         return getCorrespondingOutputLineFromFullSource(filePath, line);
75     }
76
77     /**
78      * Takes (class, line) and returns output line. If <code>class</code> was
79      * not compiled with AJC, it will return <code>line</code>. If this line
80      * does not map to the output file, this method will return the greatest
81      * line number less that <code>line</code> that does.
82      */

83     static SourceLine getCorrespondingOutputLineFromFullSource(String JavaDoc filePath,
84                                                                       int line) {
85         //
86
// The filePath is null when a non-AJC-compiled class was passed in.
87
//
88
if (filePath == null) {
89             return AJLineMapper.unknownFileSourceLine(line);
90         }
91
92         //
93
// If filePath is not null, then we can map it to the ajworkingdir.
94
// We go backwards until a valid line number is found. We can't go
95
// forward because we have no bound in that direction.
96
//
97
int lineNo = -1;
98         String JavaDoc newFile = UNKNOWN_SOURCE_STRING;
99         SourceLine sl = null;
100         line++;
101         while (--line >= 0 && lineNo == -1) {
102             sl = symbolManager.mapToOutputLine(filePath, line);
103 // //palm.util.Util.debug("filePath=" + filePath + ", line=" + line + ", sl=" + sl);
104
if (sl != null) {
105                 lineNo = sl.line;
106                 newFile = sl.filename;
107             }
108         }
109
110         if (lineNo == -1) {
111             return nonMappingSourceLine();
112         } else {
113                 //palm.util.Util.debug("Returning " + sl);
114
return new SourceLine(newFile, lineNo + 1);
115         }
116     }
117
118     /**
119       * TODO: move to org.aspectj.tools.SymbolManager
120       *
121       * @param methodName method name without type or parameter list
122       * @return method name with ajc-specific name mangling removed, unchanged if it's a Java name
123       */

124     public static String JavaDoc translateGeneratedMethodName(String JavaDoc methodName) {
125         String JavaDoc sigToken = "$signature";
126         String JavaDoc memberToken = "$member";
127         String JavaDoc staticMemberToken = "$static$member";
128         String JavaDoc adviceToken = "$reception";
129         String JavaDoc aroundToken = "$around$reception";
130         int sigTokenStart = methodName.indexOf(sigToken);
131         int memberTokenStart = methodName.indexOf(memberToken);
132         int staticMemberTokenStart = methodName.indexOf(staticMemberToken);
133         int adviceTokenStart = methodName.indexOf(adviceToken);
134         int aroundTokenStart = methodName.indexOf(aroundToken);
135         int indexNameStart = methodName.lastIndexOf("$");
136         if (sigTokenStart > -1 && indexNameStart > -1) {
137             return methodName.substring(methodName.indexOf("$")+1, sigTokenStart);
138         }
139         else if (staticMemberTokenStart > -1 && indexNameStart > -1) {
140             return methodName.substring(methodName.indexOf("$")+1, staticMemberTokenStart);
141         }
142         else if (memberTokenStart > -1 && indexNameStart > -1) {
143             return methodName.substring(methodName.indexOf("$")+1, memberTokenStart);
144         }
145         else if (adviceTokenStart > -1 && indexNameStart > -1) {
146             String JavaDoc adviceNumber = methodName.substring(adviceTokenStart + adviceToken.length());
147             return "<advice #" + adviceNumber +">";
148         }
149         else if (aroundTokenStart > -1 && indexNameStart > -1) {
150             String JavaDoc adviceNumber = methodName.substring(aroundTokenStart + aroundToken.length());
151             return "<advice #" + adviceNumber +">";
152         }
153         else {
154             return methodName;
155         }
156     }
157
158     public static String JavaDoc getCorrespondingFile(Location loc) {
159         String JavaDoc filename = "";
160         String JavaDoc qualifiedName = null;
161         try {
162             String JavaDoc locName = loc.declaringType().name();
163             String JavaDoc sourceName = loc.declaringType().sourceName();
164             String JavaDoc strippedSourceName = sourceName.substring(0, sourceName.indexOf(".java"));
165
166             String JavaDoc packageName = locName.substring(0, locName.indexOf(strippedSourceName));
167             qualifiedName = packageName + strippedSourceName;
168             filename = getFileNameFromQualified(qualifiedName, true);
169
170         } catch (AbsentInformationException aie) {
171
172         } //catch (AJLineMapperException
173
return filename;
174     }
175
176     /**
177      * Given a class, this will return the source file in which it was
178      * declared. If the class wasn't compiled with AJC, it will return null;
179      */

180     public static String JavaDoc getSourceFilePathFromAJCClass(String JavaDoc classID) {
181
182         // First, look in the outlaw hash to see if this classID was already
183
// denied
184
if (noAJCHash.get(classID) != null) {
185             return null;
186         }
187
188         // Second, see if this class was compiled with AJC. If it was it will
189
// have a file in the ajworkingdir, and that file will point at the
190
// source file in which the class we're looking for is.
191
String JavaDoc ajFile = getFileNameFromQualified(classID, true);
192
193         SourceLine sourceLine = null;
194         String JavaDoc filePath = null;
195         if (new File(ajFile).exists()) {
196             for (int i = 0; i < 1000 && sourceLine == null; i++) {
197                 if ( (sourceLine = symbolManager.mapToSourceLine(ajFile, i)) != null) {
198                     filePath = sourceLine.filename;
199                 }
200             }
201         } else {
202             // Store the outlaw for the next time
203
noAJCHash.put(classID, classID);
204             return null;
205         }
206         return filePath;
207     }
208
209     /**
210      * ajworkingdir -> src
211      */

212     public static SourceLine getCorrespondingLine(Location loc) {
213         SourceLine ajline = null;
214         String JavaDoc qualifiedName = null;
215         try {
216             qualifiedName = getQualifiedNameForSource(loc);
217             int locLineNumber = loc.lineNumber();
218             ajline = getCorrespondingLine(qualifiedName, locLineNumber);
219
220             //HERE//palm.util.Util.debug("AJLine: " + ajline + " for " + qualifiedName + ":" + locLineNumber);
221

222             // If ajline doesn't map, we'll try to map it via the dec parser
223
if (ajline != null &&
224                 ajline.line == AJLineMapper.NON_MAPPING_SOURCE_LINE) {
225                 String JavaDoc classMethodString = loc.method() + "";
226                 classMethodString = classMethodString.substring
227                                         (0, classMethodString.indexOf(")")+1);
228                 int i2dot = classMethodString.indexOf("(");
229                 int numDots = 0;
230                 while (i2dot > -1) {
231                     if (classMethodString.charAt(i2dot) == '.') {
232                         if ((++numDots) == 2) {
233                             break;
234                         }
235                     }
236                     i2dot--;
237                 }
238                 if (i2dot != -1) {
239                     classMethodString = classMethodString.substring(i2dot + 1);
240                 }
241                 String JavaDoc ajFile = AJLineMapper.getSourceFilePathFromAJCClass
242                                                 (loc.declaringType().name());
243                 if (ajFile != null) {
244                     int line = AJDecParser.getMethodLineNumber
245                                                     (ajFile, classMethodString);
246                     ajline = new SourceLine(ajFile, line);
247                 } else {
248                     ajline = new SourceLine(loc.sourceName(), loc.lineNumber());
249                 }
250             }
251         } catch (AbsentInformationException aie) {
252         }
253         return (ajline == null) ? emptySourceLine() : ajline;
254     }
255
256     /**
257      * Returns whether this is an unkown source file.
258      */

259     public static boolean isUnknownSource(String JavaDoc source) {
260         return source.equals(AJLineMapper.UNKNOWN_SOURCE_STRING);
261     }
262
263     static String JavaDoc getQualifiedNameForSource(Location loc)
264                                     throws AbsentInformationException {
265         ReferenceType refType = loc.declaringType();
266         if (refType == null) {
267             throw new AbsentInformationException();
268         }
269         String JavaDoc locName = refType.name();
270         String JavaDoc sourceName = loc.sourceName();
271         String JavaDoc strippedSourceName =
272         sourceName.substring(0, sourceName.indexOf(".java"));
273         int lastDot = locName.lastIndexOf('.');
274         String JavaDoc packageName = "";
275         if (lastDot != -1) {
276             packageName = locName.substring(0, lastDot+1);
277         }
278         String JavaDoc qualifiedName = packageName + strippedSourceName;
279         return qualifiedName;
280     }
281
282     private static SourceLine emptySourceLine() {
283         return new SourceLine(NO_SOURCE_STRING, NO_SOURCE_LINE);
284     }
285
286     private static SourceLine nonMappingSourceLine() {
287         return new SourceLine(NON_MAPPING_SOURCE_STRING, NON_MAPPING_SOURCE_LINE);
288     }
289
290     private static SourceLine unknownFileSourceLine(int line) {
291         return new SourceLine(UNKNOWN_SOURCE_STRING, line);
292     }
293
294     public static SourceLine getCorrespondLineFromFullSource(String JavaDoc filePath,
295                                                              int line) {
296         SourceLine newLine = null;
297         if (new File(filePath).exists()) {
298             int offsetLine = -1;
299             try {
300                 offsetLine = line - 1; // HACK!
301
newLine = symbolManager.mapToSourceLine
302                         (new File(filePath).getCanonicalPath(), offsetLine);
303                         //FILE-HERE
304
// (new File(filePath).getAbsolutePath(), offsetLine);
305
} catch (IOException ioe) {
306             }
307             if (newLine == null) {
308                 //
309
// The file exists, but there is there corresponding mapping
310
//
311
return nonMappingSourceLine();
312             }
313             //
314
// Good mapping
315
//
316
return newLine;
317         }
318         //
319
// No workingdir file
320
//
321
return new SourceLine(AJLineMapper.UNKNOWN_SOURCE_STRING, line);
322
323     }
324
325     /**
326      * ajworkingdir -> src
327      */

328     public static SourceLine getCorrespondingLine(String JavaDoc qualifiedName, int line) {
329         String JavaDoc filePath = getFileNameFromQualified(qualifiedName, true);
330         return getCorrespondLineFromFullSource(filePath, line);
331     }
332
333     /**
334      * ajworkingdir -> src
335      */

336     public static SourceLine getCorrespondingLineFromSource(String JavaDoc sourceName,
337                                                             int line) {
338         String JavaDoc filePath = AJLineMapper.insertWorkingDir(sourceName);
339         return getCorrespondLineFromFullSource(filePath, line);
340     }
341
342     static String JavaDoc getFileNameFromQualified(String JavaDoc qualifiedName, boolean inAJWorkingDir) { //Util.debug("getFileNameFromQualified: " + qualifiedName);
343

344         //PALM: Inner classes would be located in the parent file
345
String JavaDoc qualifiedNameNoDollars = AJLineMapper.stripDollarsFrom(qualifiedName);
346
347         //PALM: String offset = Env.getSourcePath();
348
String JavaDoc offset = ComponentRepository.getSourcePane().getSourcePath() + "";
349         if (inAJWorkingDir) {
350             offset += "/ajworkingdir";
351         }
352         String JavaDoc sourcePath = new File(offset).getAbsolutePath();
353
354         //String filename = qualifiedName.replace('.', File.separatorChar) + ".java"; // HACK: coded dirsepchar
355
String JavaDoc filename = qualifiedNameNoDollars.replace('.', File.separatorChar) + ".java";
356         return sourcePath + File.separator + filename;
357     }
358
359     //PALM: Added this method to add the file offset and ajworking to a file name
360
static String JavaDoc getFullFileNameFromFile(String JavaDoc fullName, boolean inAJWorkingDir) {
361         //PALM: String offset = Env.getSourcePath();
362
String JavaDoc offset = ComponentRepository.getSourcePane().getSourcePath() + "";
363         if (inAJWorkingDir) {
364             offset += "/ajworkingdir";
365         }
366         String JavaDoc sourcePath = new File(offset).getAbsolutePath();
367         if (fullName.indexOf(offset) == -1) {
368             return new File(sourcePath + File.separator + fullName).getAbsolutePath();
369         } else {
370             return new File(fullName).getAbsolutePath();
371         }
372     }
373
374     //PALM: Added this method to add the file offset and ajworking to a file name
375
static String JavaDoc getFullFileNameFromLocation(Location loc, boolean inAJWorkingDir)
376             throws AbsentInformationException {
377         //PALM: String offset = Env.getSourcePath();
378
String JavaDoc offset = ComponentRepository.getSourcePane().getSourcePath() + "";
379         if (inAJWorkingDir) {
380             offset += "/ajworkingdir";
381         }
382         String JavaDoc fullName = loc.declaringType().name();
383         String JavaDoc srcName = loc.sourceName();
384         String JavaDoc pkg = "";
385         int iDot = fullName.lastIndexOf(".");
386         if (iDot != -1) {
387             pkg = fullName.substring(0, iDot);
388             pkg = pkg.replace('.', File.separatorChar);
389         }
390         String JavaDoc srcPath = pkg + File.separator + srcName;
391
392         String JavaDoc sourcePath = new File(offset).getAbsolutePath();
393         if (srcPath.indexOf(offset) == -1) {
394             return new File(sourcePath + File.separator + srcPath).getAbsolutePath();
395         } else {
396             return new File(srcPath).getAbsolutePath();
397         }
398     }
399
400     static String JavaDoc removeRootAndAJWorkingDir(String JavaDoc fullPath) {
401         String JavaDoc offset =
402             ComponentRepository.getSourcePane().getSourcePath() + File.separator +
403             "ajworkingdir" + File.separator;
404         int index = offset.length();
405         if (!fullPath.startsWith(offset)) {
406             return fullPath;
407         }
408         String JavaDoc returnString = fullPath.substring(index);
409         return returnString;
410     }
411
412     static String JavaDoc removeRoot(String JavaDoc fullPath) {
413         String JavaDoc offset = "";
414         int index;
415 // try {
416
String JavaDoc path = ComponentRepository.getSourcePane().getSourcePath() + "";
417             path += File.separator + "ajworkingdir" + File.separator;
418             File file = new File(path);
419 // offset = file.getCanonicalPath();
420
offset = file.getAbsolutePath();
421 // } catch (Exception e) {
422
// return fullPath;
423
// }
424
if (fullPath.startsWith(offset)) {
425             index = offset.length();
426             return fullPath.substring(index+1);
427         }
428         offset = "";
429 // try {
430
/*File*/ file = new File(ComponentRepository.getSourcePane().getSourcePath() + "");
431 // offset = file.getCanonicalPath();
432
offset = file.getAbsolutePath();
433 // } catch (Exception e) {
434
// return fullPath;
435
// }
436
if (fullPath.startsWith(offset)) {
437             index = offset.length();
438             return fullPath.substring(index+1);
439         }
440         return fullPath;
441     }
442
443     static String JavaDoc stripDollarsFrom(String JavaDoc str) {
444         int index = str.indexOf("$");
445         if (index != -1) {
446             return str.substring(0, index);
447         }
448         return str;
449     }
450
451     static String JavaDoc insertWorkingDir(String JavaDoc fullPath) {
452         String JavaDoc path = ComponentRepository.getSourcePane().getSourcePath() + "";
453         //
454
// If fullPath already has a ajwd, return fullpath
455
//
456
if (fullPath.indexOf("ajworkingdir") != -1) {
457             return fullPath;
458         }
459         //
460
// If the root doesn't exist use getFullFileNextFromFile
461
//
462
int ipath = fullPath.indexOf(path);
463         if (ipath == -1) {
464             return AJLineMapper.getFullFileNameFromFile(fullPath, true);
465         }
466         //
467
// Add the path and ajwd to fullPath
468
//
469
String JavaDoc rest = fullPath.substring(ipath + path.length() + 1);
470         return path + File.separator +
471                 "ajworkingdir" + File.separator +
472                 rest;
473     }
474 }
Popular Tags