Пример #1
0
  public CommentsCollection parse(final InputStream in, final String charsetName)
      throws IOException, UnsupportedEncodingException {
    boolean lastWasASlashR = false;
    BufferedReader br = new BufferedReader(new InputStreamReader(in, charsetName));
    CommentsCollection comments = new CommentsCollection();
    int r;

    Deque prevTwoChars = new LinkedList<Character>(Arrays.asList('z', 'z'));

    State state = State.CODE;
    LineComment currentLineComment = null;
    BlockComment currentBlockComment = null;
    StringBuffer currentContent = null;

    int currLine = 1;
    int currCol = 1;

    while ((r = br.read()) != -1) {
      char c = (char) r;
      if (c == '\r') {
        lastWasASlashR = true;
      } else if (c == '\n' && lastWasASlashR) {
        lastWasASlashR = false;
        continue;
      } else {
        lastWasASlashR = false;
      }
      switch (state) {
        case CODE:
          if (prevTwoChars.peekLast().equals('/') && c == '/') {
            currentLineComment = new LineComment();
            currentLineComment.setBeginLine(currLine);
            currentLineComment.setBeginColumn(currCol - 1);
            state = State.IN_LINE_COMMENT;
            currentContent = new StringBuffer();
          } else if (prevTwoChars.peekLast().equals('/') && c == '*') {
            currentBlockComment = new BlockComment();
            currentBlockComment.setBeginLine(currLine);
            currentBlockComment.setBeginColumn(currCol - 1);
            state = State.IN_BLOCK_COMMENT;
            currentContent = new StringBuffer();
          } else if (c == '"') {
            state = State.IN_STRING;
          } else {
            // nothing to do
          }
          break;
        case IN_LINE_COMMENT:
          if (c == '\n' || c == '\r') {
            currentLineComment.setContent(currentContent.toString());
            currentLineComment.setEndLine(currLine);
            currentLineComment.setEndColumn(currCol);
            comments.addComment(currentLineComment);
            state = State.CODE;
          } else {
            currentContent.append(c);
          }
          break;
        case IN_BLOCK_COMMENT:
          if (prevTwoChars.peekLast().equals('*')
              && c == '/'
              && !prevTwoChars.peekFirst().equals('/')) {

            // delete last character
            String content =
                currentContent.deleteCharAt(currentContent.toString().length() - 1).toString();

            if (content.startsWith("*")) {
              JavadocComment javadocComment = new JavadocComment();
              javadocComment.setContent(content.substring(1));
              javadocComment.setBeginLine(currentBlockComment.getBeginLine());
              javadocComment.setBeginColumn(currentBlockComment.getBeginColumn());
              javadocComment.setEndLine(currLine);
              javadocComment.setEndColumn(currCol + 1);
              comments.addComment(javadocComment);
            } else {
              currentBlockComment.setContent(content);
              currentBlockComment.setEndLine(currLine);
              currentBlockComment.setEndColumn(currCol + 1);
              comments.addComment(currentBlockComment);
            }
            state = State.CODE;
          } else {
            currentContent.append(c == '\r' ? '\n' : c);
          }
          break;
        case IN_STRING:
          if (!prevTwoChars.peekLast().equals('\\') && c == '"') {
            state = State.CODE;
          }
          break;
        default:
          throw new RuntimeException("Unexpected");
      }
      switch (c) {
        case '\n':
        case '\r':
          currLine += 1;
          currCol = 1;
          break;
        case '\t':
          currCol += COLUMNS_PER_TAB;
          break;
        default:
          currCol += 1;
      }
      prevTwoChars.remove();
      prevTwoChars.add(c);
    }

    if (state == State.IN_LINE_COMMENT) {
      currentLineComment.setContent(currentContent.toString());
      currentLineComment.setEndLine(currLine);
      currentLineComment.setEndColumn(currCol);
      comments.addComment(currentLineComment);
    }

    return comments;
  }
  /**
   *
   *
   * <h1>Parse a raw comment.</h1>
   *
   * <p>Create an instance the same as the argument comment but with the revision year <br>
   * updated if needed. Return the default comment if the argument comment is null <br>
   * or an empty string.
   *
   * @param comment the original comment from the file.
   * @param commentStyle the comment style. {@link CopyrightComment}
   * @return {@link AdvancedCopyrightComment} an copyright comment with the year updated.
   */
  public static AdvancedCopyrightComment parse(BlockComment commentBock, int commentStyle) {
    // If the given comment is empty, return the default comment.
    if (commentBock == null) {
      return defaultComment(commentStyle);
    }

    String comment = commentBock.getContents();

    // identify which line delimiter is used. (for writing back to file )
    String fileLineDelimiter = TextUtilities.determineLineDelimiter(comment, "\n"); // $NON-NLS-1$

    // Split Comment into Seperate lines for easier proccessing:
    String commentLines[] = comment.split("\\r?\\n"); // $NON-NLS-1$

    // lines before the line with the year comment on it.
    StringBuilder preYearLines = new StringBuilder();

    // line with the year(s) on it. 'copyright 2002, 2010-2011 ... etc..
    String yearLine = null;

    // Lines after the line with the year comment on it.
    StringBuilder postYearLines = new StringBuilder();

    // Break down the comment into the three sections.
    boolean yearFound = false;
    String line;
    for (int i = 0; i < commentLines.length; i++) {

      line = commentLines[i]; // for clarity.

      if (yearFound) {
        // We have already found the year line and are just appending the last lines.

        // Conditionally append a newline delimiter.
        if (i != (commentLines.length - 1)) {
          // normally, append a new line.
          postYearLines.append(line + fileLineDelimiter);
        } else {
          // for the last line, only append if the original comment had a newline delimiter.
          Character lastchar = comment.charAt(comment.length() - 1);
          if (Character.isWhitespace(lastchar)) {
            postYearLines.append(line + lastchar);
          } else {
            postYearLines.append(line);
          }
        }

      } else if (line.matches(".*" + YEAR_REGEX + ".*")) { // $NON-NLS-1$ //$NON-NLS-2$
        // We found the line with the copy-right years on it.
        yearFound = true;
        yearLine = line + fileLineDelimiter;
      } else {
        // We are parsting the top part of the comment and have not reached the year-line yet.
        preYearLines.append(line + fileLineDelimiter);
      }
    }

    // The comment didn't contain any years that we can update.
    if (!yearFound) {
      return null;
    }

    // Determine first year.
    int createdYear = getFirstYear(yearLine);
    if (createdYear == 0) {
      return null; // Failed to read a year.
    }

    int yearsOnLine = countYearsOnLine(yearLine);
    // Determine the last year
    int revisedYear;
    if (yearsOnLine == 1) {
      revisedYear = -1;
    } else {
      revisedYear = getLastYear(yearLine);
    }

    return new AdvancedCopyrightComment(
        commentStyle,
        createdYear,
        revisedYear,
        yearsOnLine,
        preYearLines.toString(),
        yearLine,
        postYearLines.toString());
  }