1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.jasper.compiler;
19
20 import java.util.ArrayList;
21 import java.util.List;
22
23 /***
24 * Represents a source map (SMAP), which serves to associate lines
25 * of the input JSP file(s) to lines in the generated servlet in the
26 * final .class file, according to the JSR-045 spec.
27 *
28 * @author Shawn Bayern
29 */
30 public class SmapGenerator {
31
32 //**********************************************************************
33 // Overview
34
35 /*
36 * The SMAP syntax is reasonably straightforward. The purpose of this
37 * class is currently twofold:
38 * - to provide a simple but low-level Java interface to build
39 * a logical SMAP
40 * - to serialize this logical SMAP for eventual inclusion directly
41 * into a .class file.
42 */
43
44
45 //**********************************************************************
46 // Private state
47
48 private String outputFileName;
49 private String defaultStratum = "Java";
50 private List strata = new ArrayList();
51 private List embedded = new ArrayList();
52 private boolean doEmbedded = true;
53
54 //*********************************************************************
55 // Methods for adding mapping data
56
57 /**
58 * Sets the filename (without path information) for the generated
59 * source file. E.g., "foo$jsp.java".
60 */
61 public synchronized void setOutputFileName(String x) {
62 outputFileName = x;
63 }
64
65 /***
66 * Adds the given SmapStratum object, representing a Stratum with
67 * logically associated FileSection and LineSection blocks, to
68 * the current SmapGenerator. If <tt>default</tt> is true, this
69 * stratum is made the default stratum, overriding any previously
70 * set default.
71 *
72 * @param stratum the SmapStratum object to add
73 * @param defaultStratum if <tt>true</tt>, this SmapStratum is considered
74 * to represent the default SMAP stratum unless
75 * overwritten
76 */
77 public synchronized void addStratum(SmapStratum stratum,
78 boolean defaultStratum) {
79 strata.add(stratum);
80 if (defaultStratum)
81 this.defaultStratum = stratum.getStratumName();
82 }
83
84 /***
85 * Adds the given string as an embedded SMAP with the given stratum name.
86 *
87 * @param smap the SMAP to embed
88 * @param stratumName the name of the stratum output by the compilation
89 * that produced the <tt>smap</tt> to be embedded
90 */
91 public synchronized void addSmap(String smap, String stratumName) {
92 embedded.add("*O " + stratumName + "\n"
93 + smap
94 + "*C " + stratumName + "\n");
95 }
96
97 /***
98 * Instructs the SmapGenerator whether to actually print any embedded
99 * SMAPs or not. Intended for situations without an SMAP resolver.
100 *
101 * @param status If <tt>false</tt>, ignore any embedded SMAPs.
102 */
103 public void setDoEmbedded(boolean status) {
104 doEmbedded = status;
105 }
106
107 //**********************************************************************
108 // Methods for serializing the logical SMAP
109
110 public synchronized String getString() {
111 // check state and initialize buffer
112 if (outputFileName == null)
113 throw new IllegalStateException();
114 StringBuffer out = new StringBuffer();
115
116 // start the SMAP
117 out.append("SMAP\n");
118 out.append(outputFileName + '\n');
119 out.append(defaultStratum + '\n');
120
121 // include embedded SMAPs
122 if (doEmbedded) {
123 int nEmbedded = embedded.size();
124 for (int i = 0; i < nEmbedded; i++) {
125 out.append(embedded.get(i));
126 }
127 }
128
129 // print our StratumSections, FileSections, and LineSections
130 int nStrata = strata.size();
131 for (int i = 0; i < nStrata; i++) {
132 SmapStratum s = (SmapStratum) strata.get(i);
133 out.append(s.getString());
134 }
135
136 // end the SMAP
137 out.append("*E\n");
138
139 return out.toString();
140 }
141
142 public String toString() {
143 return getString();
144 }
145
146 //*********************************************************************
147 // For testing (and as an example of use)...
148
149 public static void main(String args[]) {
150 SmapGenerator g = new SmapGenerator();
151 g.setOutputFileName("foo.java");
152 SmapStratum s = new SmapStratum("JSP");
153 s.addFile("foo.jsp");
154 s.addFile("bar.jsp", "/foo/foo/bar.jsp");
155 s.addLineData(1, "foo.jsp", 1, 1, 1);
156 s.addLineData(2, "foo.jsp", 1, 6, 1);
157 s.addLineData(3, "foo.jsp", 2, 10, 5);
158 s.addLineData(20, "bar.jsp", 1, 30, 1);
159 g.addStratum(s, true);
160 System.out.print(g);
161
162 System.out.println("---");
163
164 SmapGenerator embedded = new SmapGenerator();
165 embedded.setOutputFileName("blargh.tier2");
166 s = new SmapStratum("Tier2");
167 s.addFile("1.tier2");
168 s.addLineData(1, "1.tier2", 1, 1, 1);
169 embedded.addStratum(s, true);
170 g.addSmap(embedded.toString(), "JSP");
171 System.out.println(g);
172 }
173 }