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