linemap.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 553 行

JAVA
553
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.java;import com.caucho.util.CharBuffer;import java.io.CharArrayWriter;import java.io.IOException;import java.io.OutputStream;import java.io.PrintWriter;import java.io.Serializable;import java.util.ArrayList;import java.util.Iterator;/** * LineMap maps generated code lines back to the source lines. * * <p>Resin uses LineMap to tell the user the line in the JSP or XSL * file that is broken, as opposed to the generated Java line. */public class LineMap implements Serializable {  private String _dstFilename;  private String _srcFilename;  private String _srcType = "JSP";    private String _lastSrcFilename;    private ArrayList<Line> _lines = new ArrayList<Line>();  /**   * Null-arg constructor for serialization.   */  public LineMap()  {  }  public LineMap(String dstFilename, String srcFilename)  {    int tail = dstFilename.lastIndexOf('/');    if (tail < 0)      _dstFilename = dstFilename;    else      dstFilename = dstFilename.substring(tail + 1);        _srcFilename = srcFilename;    _lastSrcFilename = _srcFilename;  }  public LineMap(String dstFilename)  {    int tail = dstFilename.lastIndexOf('/');    if (tail < 0)      _dstFilename = dstFilename;    else      _dstFilename = dstFilename.substring(tail + 1);   }  public void setSourceType(String type)  {    _srcType = type;  }  public String getSourceType()  {    return _srcType;  }  public String getDestFilename()  {    return _dstFilename;  }  public String getLastSourceFilename()  {    return _lastSrcFilename;  }  /**   * Adds a new line map entry.   *   * <p>LineMap assumes that dstLine increases monotonically.   *   * @param srcFilename the source filename, e.g. the included filename   * @param srcLine the source line, e.g. the line in the included file   * @param dstLine the line of the generated file.   *   * @return true if a new entry is needed   */  public boolean add(String srcFilename, int srcLine, int dstLine)  {    _lastSrcFilename = srcFilename;    if (_lines.size() > 0) {      Line line = _lines.get(_lines.size() - 1);      if (line.add(srcFilename, srcLine, dstLine)) {	if (_lines.size() > 1) {	  Line prevLine = _lines.get(_lines.size() - 2);	  if (prevLine.merge(line)) {	    _lines.remove(_lines.size() - 1);	  }	}	return true;      }      if (line.getLastDestinationLine() + 1 < dstLine) {	_lines.add(new Line(line.getLastSourceLine(),			    line.getSourceFilename(),			    1,			    line.getLastDestinationLine() + 1,			    dstLine - line.getLastDestinationLine()));      }    }        _lines.add(new Line(srcFilename, srcLine, dstLine));    return true;  }  /**   * Adds a line from the smap   */  public void addLine(int startLine, String sourceFile, int repeatCount,		      int outputLine, int outputIncrement)  {    _lines.add(new Line(startLine, sourceFile, repeatCount,			outputLine, outputIncrement));  }    public void add(int srcLine, int dstLine)  {    add(_lastSrcFilename, srcLine, dstLine);  }  public Iterator<Line> iterator()  {    return _lines.iterator();  }  public int size()  {    return _lines.size();  }  public Line get(int i)  {    return _lines.get(i);  }  public Line getLine(int line)  {    for (int i = 0; i < _lines.size(); i++) {      Line map = _lines.get(i);      if (map._dstLine <= line && line <= map.getLastDestinationLine()) {        return map;      }    }    return null;  }  /**   * Converts an error in the generated file to a CompileError based on   * the source.   */  public String convertError(String filename, int line,			     int column, String message)  {    String srcFilename = null;    int destLine = 0;    int srcLine = 0;        for (int i = 0; i < _lines.size(); i++) {      Line map = _lines.get(i);      if (filename != null && ! filename.endsWith(_dstFilename)) {      }      else if (map._dstLine <= line && line <= map.getLastDestinationLine()) {	srcFilename = map._srcFilename;	srcLine = map.getSourceLine(line);      }    }    if (srcFilename != null)      return srcFilename + ":" + srcLine + ": " + message;    else      return filename + ":" + line + ": " + message;  }  public String convertLine(String filename, int line)  {    Line bestLine = getLine(line);    if (bestLine != null)      return bestLine.getSourceFilename() + ":" + bestLine.getSourceLine(line);    else      return filename + ":" + line;  }  /**   * Filter a stack trace, replacing names.   */  public void printStackTrace(Throwable e, OutputStream os)  {    CharArrayWriter writer = new CharArrayWriter();    PrintWriter pw = new PrintWriter(writer);        e.printStackTrace(pw);    pw.close();    char []array = writer.toCharArray();    CharBuffer cb = filter(array);    if (os != null) {      byte []b = cb.toString().getBytes();      try {	os.write(b, 0, b.length);      } catch (IOException e1) {      }    } else      System.out.println(cb);  }  /**   * Filter a stack trace, replacing names.   */  public void printStackTrace(Throwable e, PrintWriter os)  {    CharArrayWriter writer = new CharArrayWriter();    PrintWriter pw = new PrintWriter(writer);        e.printStackTrace(pw);    pw.close();    char []array = writer.toCharArray();    CharBuffer cb = filter(array);    if (os != null)      os.print(cb.toString());    else      System.out.println(cb);  }  /**   * Parses a Java stack trace, converting files and line numbers when   * possible.   */  private CharBuffer filter(char []array)  {    CharBuffer buf = new CharBuffer();    CharBuffer fun = new CharBuffer();    CharBuffer file = new CharBuffer();    int i = 0;    while (i < array.length) {      fun.clear();      file.clear();      int start = i;      int end;      for (end = i; end < array.length && array[end] != '\n'; end++) {      }      for (; i < end && Character.isWhitespace(array[i]); i++) {	fun.append(array[i]);      }      // skip 'at'      for (; i < end && ! Character.isWhitespace(array[i]); i++) {	fun.append(array[i]);      }      if (! fun.endsWith("at")) {	for (i = start; i < end; i++) {	  buf.append(array[i]);	}	i = end + 1;	buf.append('\n');		continue;      }      for (; i < end && Character.isWhitespace(array[i]); i++) {      }      fun.clear();      for (; i < end && ! Character.isWhitespace(array[i]) &&	     array[i] != '('; i++) {	fun.append(array[i]);      }      if (i < end && array[i] == '(')	i++;      for (; i < end && ! Character.isWhitespace(array[i]) &&	     array[i] != ':' && array[i] != ')'; i++) {	file.append(array[i]);      }            int line = -1;      if (i < end && array[i] == ':') {	line = 0;	for (i++; i < end && array[i] >= '0' && array[i] <= '9'; i++) {	  line = 10 * line + array[i] - '0';	}      }      for (; i < end && ! Character.isWhitespace(array[i]) &&	     array[i] != ':' && array[i] != ')'; i++) {	file.append(array[i]);      }      buf.append("\tat ");      buf.append(fun);      buf.append("(");      String dstFile = file.toString();      if (dstFile.equals(_dstFilename)) {	convertError(buf, line);      }      else {	buf.append(file);	if (line > 0) {	  buf.append(":");	  buf.append(line);	}      }      buf.append(array, i, end - i);      buf.append('\n');      i = end + 1;    }    return buf;  }  /**   * Maps a destination line to an error location.   *   * @param buf CharBuffer to write the error location   * @param line generated source line to convert.   */  private void convertError(CharBuffer buf, int line)  {    String srcFilename = null;    int destLine = 0;    int srcLine = 0;    int srcTailLine = Integer.MAX_VALUE;        for (int i = 0; i < _lines.size(); i++) {      Line map = (Line) _lines.get(i);      if (map._dstLine <= line && line <= map.getLastDestinationLine()) {	srcFilename = map._srcFilename;	destLine = map._dstLine;	srcLine = map.getSourceLine(line);	break;      }    }    if (srcFilename != null) {    }    else if (_lines.size() > 0)      srcFilename = ((Line) _lines.get(0))._srcFilename;    else      srcFilename = "";    buf.append(srcFilename);    if (line >= 0) {      buf.append(":");      buf.append(srcLine + (line - destLine));    }  }  public static class Line implements Serializable {    String _srcFilename;    int _srcLine;        int _dstLine;    int _dstIncrement = 1;        int _repeat = 1;    /**     * Constructor for serialization.     */    public Line()    {    }    Line(String srcFilename, int srcLine, int dstLine)    {      _srcFilename = srcFilename;      _srcLine = srcLine;      _dstLine = dstLine;    }    Line(int srcLine, String srcFilename, int repeat,	 int dstLine, int dstIncrement)    {      _srcFilename = srcFilename;      _srcLine = srcLine;      _dstLine = dstLine;      _repeat = repeat;      _dstIncrement = dstIncrement;    }    /**     * Tries to add a new location.     */    boolean add(String srcFilename, int srcLine, int dstLine)    {      if (_srcFilename != null &&	  (! _srcFilename.equals(srcFilename) || srcFilename == null))	return false;      // XXX:      if (dstLine <= _dstLine) {	return true;      }      if (srcLine == _srcLine) {	_dstIncrement = dstLine - _dstLine + 1;	return true;      }      else if (dstLine - _dstLine == (srcLine - _srcLine) * _dstIncrement) {	_repeat = srcLine - _srcLine + 1;	return true;      }      else if (srcLine == _srcLine + 1 && _repeat == 1) {	_dstIncrement = dstLine - _dstLine;	return false;      }      /*      else if (_repeat == 1 && _dstIncrement <= 1) {	_dstIncrement = dstLine - 1 - _dstLine;	if (_dstIncrement < 0)	  _dstIncrement = 1;	return true;      }      */      return false;    }    /**     * Tries to merge two lines     */    boolean merge(Line next)    {      if (_srcFilename != null && ! _srcFilename.equals(next._srcFilename))	return false;      else if (_dstIncrement != next._dstIncrement)	return false;      else if (getLastDestinationLine() + 1 != next._dstLine)	return false;      else if (getLastSourceLine() + 1 != next._srcLine)	return false;      else {	_repeat += next._repeat;	return true;      }    }    public String getSourceFilename()    {      return _srcFilename;    }    public int getSourceLine()    {      return _srcLine;    }    /**     * Returns the source line.     */    public int getSourceLine(int dstLine)    {      return _srcLine + (dstLine - _dstLine) / _dstIncrement;    }    public int getRepeatCount()    {      return _repeat;    }    public int getDestinationLine()    {      return _dstLine;    }    public int getLastSourceLine()    {      return _srcLine + _repeat - 1;    }    public int getLastDestinationLine()    {      return _dstLine + _dstIncrement * _repeat - 1;    }    public int getDestinationIncrement()    {      return _dstIncrement;    }    public String toString()    {      return "Line[src:" + _srcFilename + ":" + _srcLine + ",dst:" + _dstLine + "]";    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?