KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jasper > compiler > SmapStratum


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.jasper.compiler;
19
20 import java.util.List JavaDoc;
21 import java.util.ArrayList JavaDoc;
22
23 /**
24  * Represents the line and file mappings associated with a JSR-045
25  * "stratum".
26  *
27  * @author Jayson Falkner
28  * @author Shawn Bayern
29  */

30 public class SmapStratum {
31
32     //*********************************************************************
33
// Class for storing LineInfo data
34

35     /**
36      * Represents a single LineSection in an SMAP, associated with
37      * a particular stratum.
38      */

39     public static class LineInfo {
40         private int inputStartLine = -1;
41         private int outputStartLine = -1;
42         private int lineFileID = 0;
43         private int inputLineCount = 1;
44         private int outputLineIncrement = 1;
45         private boolean lineFileIDSet = false;
46
47         /** Sets InputStartLine. */
48         public void setInputStartLine(int inputStartLine) {
49             if (inputStartLine < 0)
50                 throw new IllegalArgumentException JavaDoc("" + inputStartLine);
51             this.inputStartLine = inputStartLine;
52         }
53
54         /** Sets OutputStartLine. */
55         public void setOutputStartLine(int outputStartLine) {
56             if (outputStartLine < 0)
57                 throw new IllegalArgumentException JavaDoc("" + outputStartLine);
58             this.outputStartLine = outputStartLine;
59         }
60
61         /**
62              * Sets lineFileID. Should be called only when different from
63              * that of prior LineInfo object (in any given context) or 0
64              * if the current LineInfo has no (logical) predecessor.
65              * <tt>LineInfo</tt> will print this file number no matter what.
66              */

67         public void setLineFileID(int lineFileID) {
68             if (lineFileID < 0)
69                 throw new IllegalArgumentException JavaDoc("" + lineFileID);
70             this.lineFileID = lineFileID;
71             this.lineFileIDSet = true;
72         }
73
74         /** Sets InputLineCount. */
75         public void setInputLineCount(int inputLineCount) {
76             if (inputLineCount < 0)
77                 throw new IllegalArgumentException JavaDoc("" + inputLineCount);
78             this.inputLineCount = inputLineCount;
79         }
80
81         /** Sets OutputLineIncrement. */
82         public void setOutputLineIncrement(int outputLineIncrement) {
83             if (outputLineIncrement < 0)
84                 throw new IllegalArgumentException JavaDoc("" + outputLineIncrement);
85             this.outputLineIncrement = outputLineIncrement;
86         }
87
88         /**
89          * Retrieves the current LineInfo as a String, print all values
90          * only when appropriate (but LineInfoID if and only if it's been
91          * specified, as its necessity is sensitive to context).
92          */

93         public String JavaDoc getString() {
94             if (inputStartLine == -1 || outputStartLine == -1)
95                 throw new IllegalStateException JavaDoc();
96             StringBuffer JavaDoc out = new StringBuffer JavaDoc();
97             out.append(inputStartLine);
98             if (lineFileIDSet)
99                 out.append("#" + lineFileID);
100             if (inputLineCount != 1)
101                 out.append("," + inputLineCount);
102             out.append(":" + outputStartLine);
103             if (outputLineIncrement != 1)
104                 out.append("," + outputLineIncrement);
105             out.append('\n');
106             return out.toString();
107         }
108
109         public String JavaDoc toString() {
110             return getString();
111         }
112     }
113
114     //*********************************************************************
115
// Private state
116

117     private String JavaDoc stratumName;
118     private List JavaDoc fileNameList;
119     private List JavaDoc filePathList;
120     private List JavaDoc lineData;
121     private int lastFileID;
122
123     //*********************************************************************
124
// Constructor
125

126     /**
127      * Constructs a new SmapStratum object for the given stratum name
128      * (e.g., JSP).
129      *
130      * @param stratumName the name of the stratum (e.g., JSP)
131      */

132     public SmapStratum(String JavaDoc stratumName) {
133         this.stratumName = stratumName;
134         fileNameList = new ArrayList JavaDoc();
135         filePathList = new ArrayList JavaDoc();
136         lineData = new ArrayList JavaDoc();
137         lastFileID = 0;
138     }
139
140     //*********************************************************************
141
// Methods to add mapping information
142

143     /**
144      * Adds record of a new file, by filename.
145      *
146      * @param filename the filename to add, unqualified by path.
147      */

148     public void addFile(String JavaDoc filename) {
149         addFile(filename, filename);
150     }
151
152     /**
153      * Adds record of a new file, by filename and path. The path
154      * may be relative to a source compilation path.
155      *
156      * @param filename the filename to add, unqualified by path
157      * @param filePath the path for the filename, potentially relative
158      * to a source compilation path
159      */

160     public void addFile(String JavaDoc filename, String JavaDoc filePath) {
161         int pathIndex = filePathList.indexOf(filePath);
162         if (pathIndex == -1) {
163             fileNameList.add(filename);
164             filePathList.add(filePath);
165         }
166     }
167
168     /**
169      * Combines consecutive LineInfos wherever possible
170      */

171     public void optimizeLineSection() {
172
173 /* Some debugging code
174         for (int i = 0; i < lineData.size(); i++) {
175             LineInfo li = (LineInfo)lineData.get(i);
176             System.out.print(li.toString());
177         }
178 */

179         //Incorporate each LineInfo into the previous LineInfo's
180
//outputLineIncrement, if possible
181
int i = 0;
182         while (i < lineData.size() - 1) {
183             LineInfo li = (LineInfo)lineData.get(i);
184             LineInfo liNext = (LineInfo)lineData.get(i + 1);
185             if (!liNext.lineFileIDSet
186                 && liNext.inputStartLine == li.inputStartLine
187                 && liNext.inputLineCount == 1
188                 && li.inputLineCount == 1
189                 && liNext.outputStartLine
190                     == li.outputStartLine
191                         + li.inputLineCount * li.outputLineIncrement) {
192                 li.setOutputLineIncrement(
193                     liNext.outputStartLine
194                         - li.outputStartLine
195                         + liNext.outputLineIncrement);
196                 lineData.remove(i + 1);
197             } else {
198                 i++;
199             }
200         }
201
202         //Incorporate each LineInfo into the previous LineInfo's
203
//inputLineCount, if possible
204
i = 0;
205         while (i < lineData.size() - 1) {
206             LineInfo li = (LineInfo)lineData.get(i);
207             LineInfo liNext = (LineInfo)lineData.get(i + 1);
208             if (!liNext.lineFileIDSet
209                 && liNext.inputStartLine == li.inputStartLine + li.inputLineCount
210                 && liNext.outputLineIncrement == li.outputLineIncrement
211                 && liNext.outputStartLine
212                     == li.outputStartLine
213                         + li.inputLineCount * li.outputLineIncrement) {
214                 li.setInputLineCount(li.inputLineCount + liNext.inputLineCount);
215                 lineData.remove(i + 1);
216             } else {
217                 i++;
218             }
219         }
220     }
221
222     /**
223      * Adds complete information about a simple line mapping. Specify
224      * all the fields in this method; the back-end machinery takes care
225      * of printing only those that are necessary in the final SMAP.
226      * (My view is that fields are optional primarily for spatial efficiency,
227      * not for programmer convenience. Could always add utility methods
228      * later.)
229      *
230      * @param inputStartLine starting line in the source file
231      * (SMAP <tt>InputStartLine</tt>)
232      * @param inputFileName the filepath (or name) from which the input comes
233      * (yields SMAP <tt>LineFileID</tt>) Use unqualified names
234      * carefully, and only when they uniquely identify a file.
235      * @param inputLineCount the number of lines in the input to map
236      * (SMAP <tt>LineFileCount</tt>)
237      * @param outputStartLine starting line in the output file
238      * (SMAP <tt>OutputStartLine</tt>)
239      * @param outputLineIncrement number of output lines to map to each
240      * input line (SMAP <tt>OutputLineIncrement</tt>). <i>Given the
241      * fact that the name starts with "output", I continuously have
242      * the subconscious urge to call this field
243      * <tt>OutputLineExcrement</tt>.</i>
244      */

245     public void addLineData(
246         int inputStartLine,
247         String JavaDoc inputFileName,
248         int inputLineCount,
249         int outputStartLine,
250         int outputLineIncrement) {
251         // check the input - what are you doing here??
252
int fileIndex = filePathList.indexOf(inputFileName);
253         if (fileIndex == -1) // still
254
throw new IllegalArgumentException JavaDoc(
255                 "inputFileName: " + inputFileName);
256
257         //Jasper incorrectly SMAPs certain Nodes, giving them an
258
//outputStartLine of 0. This can cause a fatal error in
259
//optimizeLineSection, making it impossible for Jasper to
260
//compile the JSP. Until we can fix the underlying
261
//SMAPping problem, we simply ignore the flawed SMAP entries.
262
if (outputStartLine == 0)
263             return;
264
265         // build the LineInfo
266
LineInfo li = new LineInfo();
267         li.setInputStartLine(inputStartLine);
268         li.setInputLineCount(inputLineCount);
269         li.setOutputStartLine(outputStartLine);
270         li.setOutputLineIncrement(outputLineIncrement);
271         if (fileIndex != lastFileID)
272             li.setLineFileID(fileIndex);
273         lastFileID = fileIndex;
274
275         // save it
276
lineData.add(li);
277     }
278
279     //*********************************************************************
280
// Methods to retrieve information
281

282     /**
283      * Returns the name of the stratum.
284      */

285     public String JavaDoc getStratumName() {
286         return stratumName;
287     }
288
289     /**
290      * Returns the given stratum as a String: a StratumSection,
291      * followed by at least one FileSection and at least one LineSection.
292      */

293     public String JavaDoc getString() {
294         // check state and initialize buffer
295
if (fileNameList.size() == 0 || lineData.size() == 0)
296             return null;
297
298         StringBuffer JavaDoc out = new StringBuffer JavaDoc();
299
300         // print StratumSection
301
out.append("*S " + stratumName + "\n");
302
303         // print FileSection
304
out.append("*F\n");
305         int bound = fileNameList.size();
306         for (int i = 0; i < bound; i++) {
307             if (filePathList.get(i) != null) {
308                 out.append("+ " + i + " " + fileNameList.get(i) + "\n");
309                 // Source paths must be relative, not absolute, so we
310
// remove the leading "/", if one exists.
311
String JavaDoc filePath = (String JavaDoc)filePathList.get(i);
312                 if (filePath.startsWith("/")) {
313                     filePath = filePath.substring(1);
314                 }
315                 out.append(filePath + "\n");
316             } else {
317                 out.append(i + " " + fileNameList.get(i) + "\n");
318             }
319         }
320
321         // print LineSection
322
out.append("*L\n");
323         bound = lineData.size();
324         for (int i = 0; i < bound; i++) {
325             LineInfo li = (LineInfo)lineData.get(i);
326             out.append(li.getString());
327         }
328
329         return out.toString();
330     }
331
332     public String JavaDoc toString() {
333         return getString();
334     }
335
336 }
337
Popular Tags