KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > web > jspcompiler > SmapResolver


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.web.jspcompiler;
21
22 import java.util.*;
23 import java.io.IOException JavaDoc;
24
25 //TODO - add support for other tags, e.g. server-specific -> make sure they do not block this code
26

27 /**
28  *
29  * @author mg116726
30  */

31 public class SmapResolver {
32
33     /** header of SMAP file - must be on the first line
34      */

35     private static final String JavaDoc SMAP_HEADER = "SMAP"; // NOI18N
36

37     /** default stratum should be set to JSP
38      */

39     private static final String JavaDoc DEFAULT_STRATUM = "JSP"; //NOI18N
40

41     /** this is how JSP stratum section beginning look like
42      */

43     private static final String JavaDoc STRATUM_SECTION = "*S JSP"; // NOI18N
44

45     /** line section begins with this mark
46      */

47     private static final String JavaDoc LINE_SECTION = "*L"; // NOI18N
48

49     /** file section begins with this mark
50      */

51     private static final String JavaDoc FILE_SECTION = "*F"; // NOI18N
52

53     /** smap file ends with this mark
54      */

55     private static final String JavaDoc END_SECTION = "*E"; // NOI18N
56

57     /** this hash sign divides fileid from line number
58      */

59     private static final String JavaDoc FID_DELIM = "#"; // NOI18N
60

61     /** reader that was used to create this smapresolver
62      */

63     private SmapReader reader = null;
64     
65     /** this one is true only if the smap read by the reader has been successfully resolved
66      */

67     private boolean resolved = false;
68     
69     /** default stratum set in the smap file
70      */

71     private String JavaDoc defaultStratum = null;
72     
73     /** outputFileName ==> servlet name set in the smap file
74      */

75     private String JavaDoc outputFileName = null;
76     
77     /** contains hashmap of fileid's & filenames in the jsp
78      */

79     private Hashtable fsection = new Hashtable(3);
80     
81     /** contains jsp -> servlet line mappings
82      */

83     private Map jsp2java = new TreeMap();
84     
85     /** contains servlet -> jsp line mappings
86      */

87     private Map java2jsp = new TreeMap();
88
89     /** Creates a new instance of SmapResolver
90      * @param reader reader provides readSmap() method which returns SMAP iformation as a String
91      */

92     public SmapResolver(SmapReader reader) {
93         this.resolved = resolve(reader.readSmap());
94         this.reader = reader;
95     }
96
97     public String JavaDoc toString() {
98        return reader.toString();
99     }
100         
101     /** Reads the smap file and stores all the data into corresponding variables and maps.
102      * At the end calls sanitycheck to check whether the file has been resolved successfuly
103      * @return true if resolved successfuly, false if not
104      * @param smap SMAP information as a string
105      */

106     private boolean resolve(String JavaDoc smap) {
107         
108         String JavaDoc currentSection = "";
109         if (smap == null) return false;
110         
111         // tokenize the smap file by endlines
112
StringTokenizer st = new StringTokenizer(smap, "\n", false);
113         
114         boolean beginning = true;
115         int sectionCounter = 0; // counts items in the sections
116

117         /** to which file current indexes belong (there are more of them - includes)
118          */

119         String JavaDoc fileIndex = null;
120         
121         while (st.hasMoreTokens()) {
122             String JavaDoc token = st.nextToken();
123             
124             //this tough IF..ELSE is responsible for tracking which section is currently read
125
if (beginning) { // SMAP file begins with 'SMAP' header
126
if (!SMAP_HEADER.equals(token)) {
127                     return false;
128                 }
129                 beginning = false;
130                 currentSection = SMAP_HEADER;
131                 continue;
132             } else if (STRATUM_SECTION.equals(token)) {
133                 currentSection = STRATUM_SECTION;
134                 continue;
135             } else if (FILE_SECTION.equals(token)) {
136                 currentSection = FILE_SECTION;
137                 sectionCounter = 0;
138                 continue;
139             } else if (LINE_SECTION.equals(token)) {
140                 currentSection = LINE_SECTION;
141                 sectionCounter = 0;
142                 fileIndex = "0";
143                 continue;
144             } else if (END_SECTION.equals(token)) {
145                 currentSection = END_SECTION;
146                 break;
147             }
148
149             //read info from header
150
if (SMAP_HEADER.equals(currentSection)) {
151                 if (sectionCounter == 0) { // outputFileName
152
outputFileName = token;
153                 }
154                 if (sectionCounter == 1) { // defaultStratum follows
155
defaultStratum = token;
156                 }
157             }
158             
159             //read the file section
160
if (FILE_SECTION.equals(currentSection)) {
161                 if (token.startsWith("+")) {
162                     sectionCounter++;
163                     storeFile(token, token = st.nextToken());
164                 } else {
165                     storeFile(token, null);
166                 }
167             }
168             
169             if (LINE_SECTION.equals(currentSection)) {
170                 int hashPresent = token.indexOf(FID_DELIM);
171                 if (hashPresent > -1) { // there's a hash => there's a fileid indicator
172
fileIndex = token.substring(hashPresent + 1, token.indexOf(':'));
173                     if ((fileIndex != null) && (fileIndex.indexOf(',') > -1)) {
174                         fileIndex = fileIndex.substring(0,fileIndex.indexOf(','));
175                     }
176                     
177                 }
178                 storeLine(token, fileIndex);
179             }
180             sectionCounter++;
181         }
182         
183         //perform sanity check - report error (return false) if unsuccessful
184
this.resolved = sanityCheck();
185         return this.resolved;
186     }
187     
188     /** stores file name and file index into the fsection map
189      */

190     private void storeFile(String JavaDoc token, String JavaDoc token2) {
191         String JavaDoc id = "";
192         String JavaDoc filename = "";
193         int spaceIndex = 0;
194         if ((token != null) && (token.startsWith("+"))) {
195             token = token.substring(2);
196             spaceIndex = token.indexOf(" ");
197             id = token.substring(0, spaceIndex);
198             filename = token2;
199         } else {
200             spaceIndex = token.indexOf(" ");
201             id = token.substring(0, spaceIndex);
202             filename = token.substring(spaceIndex+1);
203         }
204         fsection.put(id, filename);
205     }
206
207     /** stores line mappings into both java->jsp->java maps
208      */

209     private void storeLine(String JavaDoc token, String JavaDoc fileIndex) {
210 // System.err.println("storeLine: " + token + ", " + fileIndex);
211
int delimIndex = token.indexOf(":");
212         
213         String JavaDoc jspLine = token.substring(0, delimIndex);
214         String JavaDoc javaLine = token.substring(delimIndex+1);
215         
216         int hashPresent = jspLine.indexOf(FID_DELIM);
217         int commaPresent = jspLine.indexOf(',');
218
219         int jspIndex = 0;
220         int repeatCount = 0;
221
222         if (commaPresent != -1) {
223             repeatCount = Integer.parseInt(jspLine.substring(commaPresent+1));
224             if (hashPresent == -1) {
225                 jspIndex = Integer.parseInt(jspLine.substring(0, commaPresent));
226             } else {
227                 jspIndex = Integer.parseInt(jspLine.substring(0, hashPresent));
228             }
229         } else {
230             if (hashPresent == -1) {
231                 jspIndex = Integer.parseInt(jspLine);
232             } else {
233                 jspIndex = Integer.parseInt(jspLine.substring(0, hashPresent));
234             }
235             repeatCount = 1;
236         }
237         
238         commaPresent = javaLine.indexOf(',');
239         
240         int outputIncrement;
241         int javaIndex;
242         if (commaPresent != -1) {
243             outputIncrement = Integer.parseInt(javaLine.substring(commaPresent+1));
244             javaIndex = Integer.parseInt(javaLine.substring(0, commaPresent));
245         } else {
246             outputIncrement = 1;
247             javaIndex = Integer.parseInt(javaLine);
248         }
249         
250         for (int i=0; i < repeatCount; i++) {
251             int jspL = jspIndex + i;
252             int javaL = javaIndex + (i * outputIncrement);
253             
254             // fill in table for jsp->java mappings
255
jspLine = Integer.toString(jspL).concat(FID_DELIM).concat(fileIndex);
256             javaLine = Integer.toString(javaL);
257             if (!jsp2java.containsKey(jspLine)) { // the first rule is the right one
258
jsp2java.put(jspLine, javaLine);
259             }
260             
261             // fill in table for java->jsp mappings
262
jspLine = Integer.toString(jspL).concat("#").concat(fileIndex);
263             javaLine = Integer.toString(javaL);
264             if (!java2jsp.containsKey(javaLine)) { // the first rule is the right one
265
java2jsp.put(javaLine, jspLine);
266             }
267         }
268     }
269     
270     /** check whether the file has been resolved correctly
271      */

272     private boolean sanityCheck() {
273         if (!DEFAULT_STRATUM.equals(defaultStratum)) return false;
274         if (!(outputFileName.endsWith(".java"))) return false;
275         if (fsection.isEmpty()) return false;
276         if (jsp2java.isEmpty()) return false; // TODO: check how this is done for empty jsps
277
if (java2jsp.isEmpty()) return false; // TODO: check how this is done for empty jsps
278
return true;
279     }
280     
281     /** access file name by index in the SMAP
282      * @param index Index of the file in the SMAP
283      * @return filename
284      */

285     private String JavaDoc getFileNameByIndex(String JavaDoc index) {
286         return (String JavaDoc)fsection.get(index);
287     }
288     
289     /** access index by the filename
290      * @param fname filename to find index for
291      * @return index of the file in SMAP
292      */

293     private String JavaDoc getIndexByFileName(String JavaDoc fname) {
294         Set s = fsection.entrySet();
295         Iterator i = s.iterator();
296         while (i.hasNext()) {
297             Map.Entry mentry = (Map.Entry)i.next();
298             String JavaDoc value = (String JavaDoc)mentry.getValue();
299             if (value.equalsIgnoreCase(fname)) {
300                 return mentry.getKey().toString();
301             }
302         }
303         return null;
304     }
305
306     /**
307      * @return Whether the SMAP info file is resolved or not
308      */

309     public boolean isResolved() {
310         return this.resolved;
311     }
312     
313     /**
314      * get all the filenames in the SMAP
315      */

316     public Map getFileNames() {
317         Hashtable h = new Hashtable(fsection.size());
318         Collection c = fsection.values();
319         Iterator i = c.iterator();
320         int counter = 0;
321         while (i.hasNext()) {
322             h.put(new Integer JavaDoc(counter++), i.next());
323         }
324         return h;
325     }
326     
327     /**
328      * get primary jsp filename
329      */

330     public String JavaDoc getPrimaryJspFileName() {
331         TreeMap tm = new TreeMap(fsection);
332         Object JavaDoc o = tm.firstKey();
333         String JavaDoc s = (String JavaDoc)fsection.get(o);
334         return s;
335     }
336
337     /** if there are included files in the jsp or not
338      */

339     public boolean hasIncludedFiles() {
340         return (fsection.size() > 1);
341     }
342     
343     public String JavaDoc getJavaLineType(int line, int col) {
344         //line type is not included in the SMAP mapping information - therefore this is not supported in JSR45
345
return null;
346     }
347     
348     /** whether the jsp file is completely empty - without any line
349      */

350     public boolean isEmpty() {
351         return jsp2java.isEmpty(); // TODO - check if this really works
352
}
353
354     /** returns jsp name for corresponding servlet line
355      */

356     public String JavaDoc getJspFileName(int line, int col) throws IOException JavaDoc {
357         String JavaDoc key = Integer.toString(line);
358         String JavaDoc value = (String JavaDoc)java2jsp.get(key);
359         if (value == null) return null;
360         String JavaDoc index = value.substring(value.indexOf(FID_DELIM)+1);
361         return getFileNameByIndex(index);
362     }
363     
364     public int mangle(String JavaDoc jspFileName, int line, int col) {
365         String JavaDoc fileIndex = getIndexByFileName(jspFileName);
366         if (fileIndex == null) return -1;
367         String JavaDoc key = "".concat(Integer.toString(line)).concat("#").concat(fileIndex);
368         String JavaDoc value = (String JavaDoc)jsp2java.get(key);
369         if (value == null) return -1;
370         return Integer.parseInt(value);
371     }
372
373     public int unmangle(int line, int col) {
374         String JavaDoc key = Integer.toString(line);
375         String JavaDoc value = (String JavaDoc)java2jsp.get(key);
376         if (value == null) return -1;
377         int jspline = Integer.parseInt(value.substring(0, value.indexOf("#")));
378         return jspline;
379     }
380     
381 // public static void main(String[] args) {
382
// SmapResolver sr = new SmapResolver(new SmapFileReader(
383
// new java.io.File("/Users/mg116726/WebApplication3/build/generated/src/org/apache/jsp/index_jsp.class.smap")));
384
// System.err.println("resolved: " + sr.isResolved());
385
// try {
386
// System.err.println(sr.getJspFileName(43,0));
387
// System.err.println(sr.unmangle(43,0));
388
// } catch (Exception e) {
389
// System.err.println("exception");
390
// }
391
// }
392
}
393
Popular Tags