/projects/tomcat-7.0.2/java/org/apache/jasper/compiler/SmapStratum.java
Java | 338 lines | 174 code | 36 blank | 128 comment | 52 complexity | 2f46336f831da19e1ef862179a05d326 MD5 | raw file
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.jasper.compiler;
- import java.util.List;
- import java.util.ArrayList;
- /**
- * Represents the line and file mappings associated with a JSR-045
- * "stratum".
- *
- * @author Jayson Falkner
- * @author Shawn Bayern
- */
- public class SmapStratum {
- //*********************************************************************
- // Class for storing LineInfo data
- /**
- * Represents a single LineSection in an SMAP, associated with
- * a particular stratum.
- */
- public static class LineInfo {
- private int inputStartLine = -1;
- private int outputStartLine = -1;
- private int lineFileID = 0;
- private int inputLineCount = 1;
- private int outputLineIncrement = 1;
- private boolean lineFileIDSet = false;
- /** Sets InputStartLine. */
- public void setInputStartLine(int inputStartLine) {
- if (inputStartLine < 0)
- throw new IllegalArgumentException("" + inputStartLine);
- this.inputStartLine = inputStartLine;
- }
- /** Sets OutputStartLine. */
- public void setOutputStartLine(int outputStartLine) {
- if (outputStartLine < 0)
- throw new IllegalArgumentException("" + outputStartLine);
- this.outputStartLine = outputStartLine;
- }
- /**
- * Sets lineFileID. Should be called only when different from
- * that of prior LineInfo object (in any given context) or 0
- * if the current LineInfo has no (logical) predecessor.
- * <tt>LineInfo</tt> will print this file number no matter what.
- */
- public void setLineFileID(int lineFileID) {
- if (lineFileID < 0)
- throw new IllegalArgumentException("" + lineFileID);
- this.lineFileID = lineFileID;
- this.lineFileIDSet = true;
- }
- /** Sets InputLineCount. */
- public void setInputLineCount(int inputLineCount) {
- if (inputLineCount < 0)
- throw new IllegalArgumentException("" + inputLineCount);
- this.inputLineCount = inputLineCount;
- }
- /** Sets OutputLineIncrement. */
- public void setOutputLineIncrement(int outputLineIncrement) {
- if (outputLineIncrement < 0)
- throw new IllegalArgumentException("" + outputLineIncrement);
- this.outputLineIncrement = outputLineIncrement;
- }
- /**
- * Retrieves the current LineInfo as a String, print all values
- * only when appropriate (but LineInfoID if and only if it's been
- * specified, as its necessity is sensitive to context).
- */
- public String getString() {
- if (inputStartLine == -1 || outputStartLine == -1)
- throw new IllegalStateException();
- StringBuilder out = new StringBuilder();
- out.append(inputStartLine);
- if (lineFileIDSet)
- out.append("#" + lineFileID);
- if (inputLineCount != 1)
- out.append("," + inputLineCount);
- out.append(":" + outputStartLine);
- if (outputLineIncrement != 1)
- out.append("," + outputLineIncrement);
- out.append('\n');
- return out.toString();
- }
- @Override
- public String toString() {
- return getString();
- }
- }
- //*********************************************************************
- // Private state
- private String stratumName;
- private List<String> fileNameList;
- private List<String> filePathList;
- private List<LineInfo> lineData;
- private int lastFileID;
- //*********************************************************************
- // Constructor
- /**
- * Constructs a new SmapStratum object for the given stratum name
- * (e.g., JSP).
- *
- * @param stratumName the name of the stratum (e.g., JSP)
- */
- public SmapStratum(String stratumName) {
- this.stratumName = stratumName;
- fileNameList = new ArrayList<String>();
- filePathList = new ArrayList<String>();
- lineData = new ArrayList<LineInfo>();
- lastFileID = 0;
- }
- //*********************************************************************
- // Methods to add mapping information
- /**
- * Adds record of a new file, by filename.
- *
- * @param filename the filename to add, unqualified by path.
- */
- public void addFile(String filename) {
- addFile(filename, filename);
- }
- /**
- * Adds record of a new file, by filename and path. The path
- * may be relative to a source compilation path.
- *
- * @param filename the filename to add, unqualified by path
- * @param filePath the path for the filename, potentially relative
- * to a source compilation path
- */
- public void addFile(String filename, String filePath) {
- int pathIndex = filePathList.indexOf(filePath);
- if (pathIndex == -1) {
- fileNameList.add(filename);
- filePathList.add(filePath);
- }
- }
- /**
- * Combines consecutive LineInfos wherever possible
- */
- public void optimizeLineSection() {
- /* Some debugging code
- for (int i = 0; i < lineData.size(); i++) {
- LineInfo li = (LineInfo)lineData.get(i);
- System.out.print(li.toString());
- }
- */
- //Incorporate each LineInfo into the previous LineInfo's
- //outputLineIncrement, if possible
- int i = 0;
- while (i < lineData.size() - 1) {
- LineInfo li = lineData.get(i);
- LineInfo liNext = lineData.get(i + 1);
- if (!liNext.lineFileIDSet
- && liNext.inputStartLine == li.inputStartLine
- && liNext.inputLineCount == 1
- && li.inputLineCount == 1
- && liNext.outputStartLine
- == li.outputStartLine
- + li.inputLineCount * li.outputLineIncrement) {
- li.setOutputLineIncrement(
- liNext.outputStartLine
- - li.outputStartLine
- + liNext.outputLineIncrement);
- lineData.remove(i + 1);
- } else {
- i++;
- }
- }
- //Incorporate each LineInfo into the previous LineInfo's
- //inputLineCount, if possible
- i = 0;
- while (i < lineData.size() - 1) {
- LineInfo li = lineData.get(i);
- LineInfo liNext = lineData.get(i + 1);
- if (!liNext.lineFileIDSet
- && liNext.inputStartLine == li.inputStartLine + li.inputLineCount
- && liNext.outputLineIncrement == li.outputLineIncrement
- && liNext.outputStartLine
- == li.outputStartLine
- + li.inputLineCount * li.outputLineIncrement) {
- li.setInputLineCount(li.inputLineCount + liNext.inputLineCount);
- lineData.remove(i + 1);
- } else {
- i++;
- }
- }
- }
- /**
- * Adds complete information about a simple line mapping. Specify
- * all the fields in this method; the back-end machinery takes care
- * of printing only those that are necessary in the final SMAP.
- * (My view is that fields are optional primarily for spatial efficiency,
- * not for programmer convenience. Could always add utility methods
- * later.)
- *
- * @param inputStartLine starting line in the source file
- * (SMAP <tt>InputStartLine</tt>)
- * @param inputFileName the filepath (or name) from which the input comes
- * (yields SMAP <tt>LineFileID</tt>) Use unqualified names
- * carefully, and only when they uniquely identify a file.
- * @param inputLineCount the number of lines in the input to map
- * (SMAP <tt>LineFileCount</tt>)
- * @param outputStartLine starting line in the output file
- * (SMAP <tt>OutputStartLine</tt>)
- * @param outputLineIncrement number of output lines to map to each
- * input line (SMAP <tt>OutputLineIncrement</tt>). <i>Given the
- * fact that the name starts with "output", I continuously have
- * the subconscious urge to call this field
- * <tt>OutputLineExcrement</tt>.</i>
- */
- public void addLineData(
- int inputStartLine,
- String inputFileName,
- int inputLineCount,
- int outputStartLine,
- int outputLineIncrement) {
- // check the input - what are you doing here??
- int fileIndex = filePathList.indexOf(inputFileName);
- if (fileIndex == -1) // still
- throw new IllegalArgumentException(
- "inputFileName: " + inputFileName);
- //Jasper incorrectly SMAPs certain Nodes, giving them an
- //outputStartLine of 0. This can cause a fatal error in
- //optimizeLineSection, making it impossible for Jasper to
- //compile the JSP. Until we can fix the underlying
- //SMAPping problem, we simply ignore the flawed SMAP entries.
- if (outputStartLine == 0)
- return;
- // build the LineInfo
- LineInfo li = new LineInfo();
- li.setInputStartLine(inputStartLine);
- li.setInputLineCount(inputLineCount);
- li.setOutputStartLine(outputStartLine);
- li.setOutputLineIncrement(outputLineIncrement);
- if (fileIndex != lastFileID)
- li.setLineFileID(fileIndex);
- lastFileID = fileIndex;
- // save it
- lineData.add(li);
- }
- //*********************************************************************
- // Methods to retrieve information
- /**
- * Returns the name of the stratum.
- */
- public String getStratumName() {
- return stratumName;
- }
- /**
- * Returns the given stratum as a String: a StratumSection,
- * followed by at least one FileSection and at least one LineSection.
- */
- public String getString() {
- // check state and initialize buffer
- if (fileNameList.size() == 0 || lineData.size() == 0)
- return null;
- StringBuilder out = new StringBuilder();
- // print StratumSection
- out.append("*S " + stratumName + "\n");
- // print FileSection
- out.append("*F\n");
- int bound = fileNameList.size();
- for (int i = 0; i < bound; i++) {
- if (filePathList.get(i) != null) {
- out.append("+ " + i + " " + fileNameList.get(i) + "\n");
- // Source paths must be relative, not absolute, so we
- // remove the leading "/", if one exists.
- String filePath = filePathList.get(i);
- if (filePath.startsWith("/")) {
- filePath = filePath.substring(1);
- }
- out.append(filePath + "\n");
- } else {
- out.append(i + " " + fileNameList.get(i) + "\n");
- }
- }
- // print LineSection
- out.append("*L\n");
- bound = lineData.size();
- for (int i = 0; i < bound; i++) {
- LineInfo li = lineData.get(i);
- out.append(li.getString());
- }
- return out.toString();
- }
- @Override
- public String toString() {
- return getString();
- }
- }