001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.jasper.compiler;
019:
020: import java.util.List;
021: import java.util.ArrayList;
022:
023: /**
024: * Represents a source map (SMAP), which serves to associate lines
025: * of the input JSP file(s) to lines in the generated servlet in the
026: * final .class file, according to the JSR-045 spec.
027: *
028: * @author Shawn Bayern
029: */
030: public class SmapGenerator {
031:
032: //*********************************************************************
033: // Overview
034:
035: /*
036: * The SMAP syntax is reasonably straightforward. The purpose of this
037: * class is currently twofold:
038: * - to provide a simple but low-level Java interface to build
039: * a logical SMAP
040: * - to serialize this logical SMAP for eventual inclusion directly
041: * into a .class file.
042: */
043:
044: //*********************************************************************
045: // Private state
046: private String outputFileName;
047: private String defaultStratum = "Java";
048: private List strata = new ArrayList();
049: private List embedded = new ArrayList();
050: private boolean doEmbedded = true;
051:
052: //*********************************************************************
053: // Methods for adding mapping data
054:
055: /**
056: * Sets the filename (without path information) for the generated
057: * source file. E.g., "foo$jsp.java".
058: */
059: public synchronized void setOutputFileName(String x) {
060: outputFileName = x;
061: }
062:
063: /**
064: * Adds the given SmapStratum object, representing a Stratum with
065: * logically associated FileSection and LineSection blocks, to
066: * the current SmapGenerator. If <tt>default</tt> is true, this
067: * stratum is made the default stratum, overriding any previously
068: * set default.
069: *
070: * @param stratum the SmapStratum object to add
071: * @param defaultStratum if <tt>true</tt>, this SmapStratum is considered
072: * to represent the default SMAP stratum unless
073: * overwritten
074: */
075: public synchronized void addStratum(SmapStratum stratum,
076: boolean defaultStratum) {
077: strata.add(stratum);
078: if (defaultStratum)
079: this .defaultStratum = stratum.getStratumName();
080: }
081:
082: /**
083: * Adds the given string as an embedded SMAP with the given stratum name.
084: *
085: * @param smap the SMAP to embed
086: * @param stratumName the name of the stratum output by the compilation
087: * that produced the <tt>smap</tt> to be embedded
088: */
089: public synchronized void addSmap(String smap, String stratumName) {
090: embedded.add("*O " + stratumName + "\n" + smap + "*C "
091: + stratumName + "\n");
092: }
093:
094: /**
095: * Instructs the SmapGenerator whether to actually print any embedded
096: * SMAPs or not. Intended for situations without an SMAP resolver.
097: *
098: * @param status If <tt>false</tt>, ignore any embedded SMAPs.
099: */
100: public void setDoEmbedded(boolean status) {
101: doEmbedded = status;
102: }
103:
104: //*********************************************************************
105: // Methods for serializing the logical SMAP
106:
107: public synchronized String getString() {
108: // check state and initialize buffer
109: if (outputFileName == null)
110: throw new IllegalStateException();
111: StringBuffer out = new StringBuffer();
112:
113: // start the SMAP
114: out.append("SMAP\n");
115: out.append(outputFileName + '\n');
116: out.append(defaultStratum + '\n');
117:
118: // include embedded SMAPs
119: if (doEmbedded) {
120: int nEmbedded = embedded.size();
121: for (int i = 0; i < nEmbedded; i++) {
122: out.append(embedded.get(i));
123: }
124: }
125:
126: // print our StratumSections, FileSections, and LineSections
127: int nStrata = strata.size();
128: for (int i = 0; i < nStrata; i++) {
129: SmapStratum s = (SmapStratum) strata.get(i);
130: out.append(s.getString());
131: }
132:
133: // end the SMAP
134: out.append("*E\n");
135:
136: return out.toString();
137: }
138:
139: public String toString() {
140: return getString();
141: }
142:
143: //*********************************************************************
144: // For testing (and as an example of use)...
145:
146: public static void main(String args[]) {
147: SmapGenerator g = new SmapGenerator();
148: g.setOutputFileName("foo.java");
149: SmapStratum s = new SmapStratum("JSP");
150: s.addFile("foo.jsp");
151: s.addFile("bar.jsp", "/foo/foo/bar.jsp");
152: s.addLineData(1, "foo.jsp", 1, 1, 1);
153: s.addLineData(2, "foo.jsp", 1, 6, 1);
154: s.addLineData(3, "foo.jsp", 2, 10, 5);
155: s.addLineData(20, "bar.jsp", 1, 30, 1);
156: g.addStratum(s, true);
157: System.out.print(g);
158:
159: System.out.println("---");
160:
161: SmapGenerator embedded = new SmapGenerator();
162: embedded.setOutputFileName("blargh.tier2");
163: s = new SmapStratum("Tier2");
164: s.addFile("1.tier2");
165: s.addLineData(1, "1.tier2", 1, 1, 1);
166: embedded.addStratum(s, true);
167: g.addSmap(embedded.toString(), "JSP");
168: System.out.println(g);
169: }
170: }
|