PageRenderTime 40ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/tomcat-7.0.2/java/org/apache/jasper/compiler/SmapStratum.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 338 lines | 174 code | 36 blank | 128 comment | 52 complexity | 2f46336f831da19e1ef862179a05d326 MD5 | raw file
  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. package org.apache.jasper.compiler;
  18. import java.util.List;
  19. import java.util.ArrayList;
  20. /**
  21. * Represents the line and file mappings associated with a JSR-045
  22. * "stratum".
  23. *
  24. * @author Jayson Falkner
  25. * @author Shawn Bayern
  26. */
  27. public class SmapStratum {
  28. //*********************************************************************
  29. // Class for storing LineInfo data
  30. /**
  31. * Represents a single LineSection in an SMAP, associated with
  32. * a particular stratum.
  33. */
  34. public static class LineInfo {
  35. private int inputStartLine = -1;
  36. private int outputStartLine = -1;
  37. private int lineFileID = 0;
  38. private int inputLineCount = 1;
  39. private int outputLineIncrement = 1;
  40. private boolean lineFileIDSet = false;
  41. /** Sets InputStartLine. */
  42. public void setInputStartLine(int inputStartLine) {
  43. if (inputStartLine < 0)
  44. throw new IllegalArgumentException("" + inputStartLine);
  45. this.inputStartLine = inputStartLine;
  46. }
  47. /** Sets OutputStartLine. */
  48. public void setOutputStartLine(int outputStartLine) {
  49. if (outputStartLine < 0)
  50. throw new IllegalArgumentException("" + outputStartLine);
  51. this.outputStartLine = outputStartLine;
  52. }
  53. /**
  54. * Sets lineFileID. Should be called only when different from
  55. * that of prior LineInfo object (in any given context) or 0
  56. * if the current LineInfo has no (logical) predecessor.
  57. * <tt>LineInfo</tt> will print this file number no matter what.
  58. */
  59. public void setLineFileID(int lineFileID) {
  60. if (lineFileID < 0)
  61. throw new IllegalArgumentException("" + lineFileID);
  62. this.lineFileID = lineFileID;
  63. this.lineFileIDSet = true;
  64. }
  65. /** Sets InputLineCount. */
  66. public void setInputLineCount(int inputLineCount) {
  67. if (inputLineCount < 0)
  68. throw new IllegalArgumentException("" + inputLineCount);
  69. this.inputLineCount = inputLineCount;
  70. }
  71. /** Sets OutputLineIncrement. */
  72. public void setOutputLineIncrement(int outputLineIncrement) {
  73. if (outputLineIncrement < 0)
  74. throw new IllegalArgumentException("" + outputLineIncrement);
  75. this.outputLineIncrement = outputLineIncrement;
  76. }
  77. /**
  78. * Retrieves the current LineInfo as a String, print all values
  79. * only when appropriate (but LineInfoID if and only if it's been
  80. * specified, as its necessity is sensitive to context).
  81. */
  82. public String getString() {
  83. if (inputStartLine == -1 || outputStartLine == -1)
  84. throw new IllegalStateException();
  85. StringBuilder out = new StringBuilder();
  86. out.append(inputStartLine);
  87. if (lineFileIDSet)
  88. out.append("#" + lineFileID);
  89. if (inputLineCount != 1)
  90. out.append("," + inputLineCount);
  91. out.append(":" + outputStartLine);
  92. if (outputLineIncrement != 1)
  93. out.append("," + outputLineIncrement);
  94. out.append('\n');
  95. return out.toString();
  96. }
  97. @Override
  98. public String toString() {
  99. return getString();
  100. }
  101. }
  102. //*********************************************************************
  103. // Private state
  104. private String stratumName;
  105. private List<String> fileNameList;
  106. private List<String> filePathList;
  107. private List<LineInfo> lineData;
  108. private int lastFileID;
  109. //*********************************************************************
  110. // Constructor
  111. /**
  112. * Constructs a new SmapStratum object for the given stratum name
  113. * (e.g., JSP).
  114. *
  115. * @param stratumName the name of the stratum (e.g., JSP)
  116. */
  117. public SmapStratum(String stratumName) {
  118. this.stratumName = stratumName;
  119. fileNameList = new ArrayList<String>();
  120. filePathList = new ArrayList<String>();
  121. lineData = new ArrayList<LineInfo>();
  122. lastFileID = 0;
  123. }
  124. //*********************************************************************
  125. // Methods to add mapping information
  126. /**
  127. * Adds record of a new file, by filename.
  128. *
  129. * @param filename the filename to add, unqualified by path.
  130. */
  131. public void addFile(String filename) {
  132. addFile(filename, filename);
  133. }
  134. /**
  135. * Adds record of a new file, by filename and path. The path
  136. * may be relative to a source compilation path.
  137. *
  138. * @param filename the filename to add, unqualified by path
  139. * @param filePath the path for the filename, potentially relative
  140. * to a source compilation path
  141. */
  142. public void addFile(String filename, String filePath) {
  143. int pathIndex = filePathList.indexOf(filePath);
  144. if (pathIndex == -1) {
  145. fileNameList.add(filename);
  146. filePathList.add(filePath);
  147. }
  148. }
  149. /**
  150. * Combines consecutive LineInfos wherever possible
  151. */
  152. public void optimizeLineSection() {
  153. /* Some debugging code
  154. for (int i = 0; i < lineData.size(); i++) {
  155. LineInfo li = (LineInfo)lineData.get(i);
  156. System.out.print(li.toString());
  157. }
  158. */
  159. //Incorporate each LineInfo into the previous LineInfo's
  160. //outputLineIncrement, if possible
  161. int i = 0;
  162. while (i < lineData.size() - 1) {
  163. LineInfo li = lineData.get(i);
  164. LineInfo liNext = lineData.get(i + 1);
  165. if (!liNext.lineFileIDSet
  166. && liNext.inputStartLine == li.inputStartLine
  167. && liNext.inputLineCount == 1
  168. && li.inputLineCount == 1
  169. && liNext.outputStartLine
  170. == li.outputStartLine
  171. + li.inputLineCount * li.outputLineIncrement) {
  172. li.setOutputLineIncrement(
  173. liNext.outputStartLine
  174. - li.outputStartLine
  175. + liNext.outputLineIncrement);
  176. lineData.remove(i + 1);
  177. } else {
  178. i++;
  179. }
  180. }
  181. //Incorporate each LineInfo into the previous LineInfo's
  182. //inputLineCount, if possible
  183. i = 0;
  184. while (i < lineData.size() - 1) {
  185. LineInfo li = lineData.get(i);
  186. LineInfo liNext = lineData.get(i + 1);
  187. if (!liNext.lineFileIDSet
  188. && liNext.inputStartLine == li.inputStartLine + li.inputLineCount
  189. && liNext.outputLineIncrement == li.outputLineIncrement
  190. && liNext.outputStartLine
  191. == li.outputStartLine
  192. + li.inputLineCount * li.outputLineIncrement) {
  193. li.setInputLineCount(li.inputLineCount + liNext.inputLineCount);
  194. lineData.remove(i + 1);
  195. } else {
  196. i++;
  197. }
  198. }
  199. }
  200. /**
  201. * Adds complete information about a simple line mapping. Specify
  202. * all the fields in this method; the back-end machinery takes care
  203. * of printing only those that are necessary in the final SMAP.
  204. * (My view is that fields are optional primarily for spatial efficiency,
  205. * not for programmer convenience. Could always add utility methods
  206. * later.)
  207. *
  208. * @param inputStartLine starting line in the source file
  209. * (SMAP <tt>InputStartLine</tt>)
  210. * @param inputFileName the filepath (or name) from which the input comes
  211. * (yields SMAP <tt>LineFileID</tt>) Use unqualified names
  212. * carefully, and only when they uniquely identify a file.
  213. * @param inputLineCount the number of lines in the input to map
  214. * (SMAP <tt>LineFileCount</tt>)
  215. * @param outputStartLine starting line in the output file
  216. * (SMAP <tt>OutputStartLine</tt>)
  217. * @param outputLineIncrement number of output lines to map to each
  218. * input line (SMAP <tt>OutputLineIncrement</tt>). <i>Given the
  219. * fact that the name starts with "output", I continuously have
  220. * the subconscious urge to call this field
  221. * <tt>OutputLineExcrement</tt>.</i>
  222. */
  223. public void addLineData(
  224. int inputStartLine,
  225. String inputFileName,
  226. int inputLineCount,
  227. int outputStartLine,
  228. int outputLineIncrement) {
  229. // check the input - what are you doing here??
  230. int fileIndex = filePathList.indexOf(inputFileName);
  231. if (fileIndex == -1) // still
  232. throw new IllegalArgumentException(
  233. "inputFileName: " + inputFileName);
  234. //Jasper incorrectly SMAPs certain Nodes, giving them an
  235. //outputStartLine of 0. This can cause a fatal error in
  236. //optimizeLineSection, making it impossible for Jasper to
  237. //compile the JSP. Until we can fix the underlying
  238. //SMAPping problem, we simply ignore the flawed SMAP entries.
  239. if (outputStartLine == 0)
  240. return;
  241. // build the LineInfo
  242. LineInfo li = new LineInfo();
  243. li.setInputStartLine(inputStartLine);
  244. li.setInputLineCount(inputLineCount);
  245. li.setOutputStartLine(outputStartLine);
  246. li.setOutputLineIncrement(outputLineIncrement);
  247. if (fileIndex != lastFileID)
  248. li.setLineFileID(fileIndex);
  249. lastFileID = fileIndex;
  250. // save it
  251. lineData.add(li);
  252. }
  253. //*********************************************************************
  254. // Methods to retrieve information
  255. /**
  256. * Returns the name of the stratum.
  257. */
  258. public String getStratumName() {
  259. return stratumName;
  260. }
  261. /**
  262. * Returns the given stratum as a String: a StratumSection,
  263. * followed by at least one FileSection and at least one LineSection.
  264. */
  265. public String getString() {
  266. // check state and initialize buffer
  267. if (fileNameList.size() == 0 || lineData.size() == 0)
  268. return null;
  269. StringBuilder out = new StringBuilder();
  270. // print StratumSection
  271. out.append("*S " + stratumName + "\n");
  272. // print FileSection
  273. out.append("*F\n");
  274. int bound = fileNameList.size();
  275. for (int i = 0; i < bound; i++) {
  276. if (filePathList.get(i) != null) {
  277. out.append("+ " + i + " " + fileNameList.get(i) + "\n");
  278. // Source paths must be relative, not absolute, so we
  279. // remove the leading "/", if one exists.
  280. String filePath = filePathList.get(i);
  281. if (filePath.startsWith("/")) {
  282. filePath = filePath.substring(1);
  283. }
  284. out.append(filePath + "\n");
  285. } else {
  286. out.append(i + " " + fileNameList.get(i) + "\n");
  287. }
  288. }
  289. // print LineSection
  290. out.append("*L\n");
  291. bound = lineData.size();
  292. for (int i = 0; i < bound; i++) {
  293. LineInfo li = lineData.get(i);
  294. out.append(li.getString());
  295. }
  296. return out.toString();
  297. }
  298. @Override
  299. public String toString() {
  300. return getString();
  301. }
  302. }