KeywordExpander.java :  » Source-Control » sourcejammer » org » sourcejammer » server » keywords » Java Open Source

Java Open Source » Source Control » sourcejammer 
sourcejammer » org » sourcejammer » server » keywords » KeywordExpander.java
/*
 *  Copyright (C) 2001, 2002 Robert MacGrogan
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 *
 * $Archive: SourceJammer$
 * $FileName: KeywordExpander.java$
 * $FileID: 4474$
 *
 * Last change:
 * $AuthorName: Rob MacGrogan$
 * $Date: 9/1/03 9:26 PM$
 * $Comment: Remove debug messages.$
 */

package org.sourcejammer.server.keywords;

import java.util.Vector;
import java.util.Iterator;
import org.sourcejammer.util.BufferedLineReader;
import java.io.IOException;
import org.sourcejammer.project.controller.FileNode;

/**
 * Title:        $FileName: KeywordExpander.java$
 * @version      $VerNum: 4$
 * @author       $AuthorName: Rob MacGrogan$<br><br>
 *
 * $Description: Parse and expand keywords.$<br>
 * $KeyWordsOff: $
 */
public abstract class KeywordExpander implements KeywordTags{

  /**
   * Expand any keywords in current line.
   *
   * @return Number of characters in all Strings added to lines Vector.
   */
  public abstract int expand(String line, int keywordBeginIndex,
                              Vector lines, ProjectObjects obj,
                              BufferedLineReader reader)
          throws KeywordExpansionException, IOException;


  public int getSeparatorIndex(int keywordBeginIndex, String keyword){
    return keywordBeginIndex + (keyword.length() - 1);
  }

  public String getBeginNewLine(int keywordBeginIndex, String line){
    return line.substring(0, keywordBeginIndex);
  }

  public String getBeginNewLineIndent(int keywordBeginIndex, String line, String keyword){
    char[] spaces = new char[keyword.length()];
    java.util.Arrays.fill(spaces, ' ');
    return getBeginNewLine(keywordBeginIndex, line) + new String(spaces);
  }



  /**
   * separatorIndex is index of separator char for keyword. Look for end of keyword value marker either in
   * line or in a subsequent line returned from reader. Replace keyword value iwth
   * value. Convert to a series of one or m ore lines which are then
   * added to Vector.
   */
  protected int replaceKeywordWithValue(int separatorIndex, String value,
                                       Vector lines, String line,
                                       BufferedLineReader reader, String commentStyle)
          throws KeywordExpansionException, IOException{

    int iNumChars = 0;
    int iBeginValueIndex = separatorIndex + 1;

    //First check if end of keyword marker is found in line.
    int iValueEndIndex = line.indexOf(KEYWORD_INDICATOR, iBeginValueIndex);

    if (iValueEndIndex > -1 ){
      //Found end of value marker in line. No need for subsequent lines.
      iNumChars = replaceSingleLine(line, iBeginValueIndex, iValueEndIndex, lines, value, commentStyle);
    }
    else{
      iNumChars = replaceMultiLine(line, iBeginValueIndex, lines, value, reader, commentStyle);
    }
    return iNumChars;
  }

  /**
   * Replaces multiple lines in text file with keyword value.
   */
  private int replaceMultiLine(String line, int iBeginValueIndex,
                                Vector lines, String value,
                                BufferedLineReader reader,
                                String commentStyle)
          throws KeywordExpansionException, IOException{
    //We need to scroll through subsequent lines looking for end of
    //value marker. Since we are replacing everything before the marker,
    //we can ignore any lines that don't contain the marker. All we need
    //are the first and final lines.

    //Also, if we don't find the marker anywhere in the file, we will throw
    //an exception. The add/check in operation will be hosed and user will
    //be required to correct the keyword problem before the add/checkin
    //can be completed.

    int iNumChars = 0;
    boolean bIndicatorFound = false;
    String nextLine = line;
    while (! bIndicatorFound){
      if (nextLine != null){
        //Look for indicator.
        int iValueEndIndex =  -1;
        if (nextLine == line){
          //It's the first line.
          nextLine.indexOf(KEYWORD_INDICATOR, iBeginValueIndex);
        }
        else {
          iValueEndIndex = nextLine.indexOf(KEYWORD_INDICATOR);
        }
        if (iValueEndIndex > -1){
          //Found it.
          String endLine = nextLine.substring(iValueEndIndex);
          String beginLine = line.substring(0, iBeginValueIndex);
          iNumChars = addValue(beginLine, endLine, value, lines, commentStyle);
          bIndicatorFound = true;
        }
      }//end if nextLine not null
      else{
        //end of file before indicator found. Throw exception.
        throw new KeywordExpansionException("End of file reached before end of keyword indicator found.");
      }
      if (! bIndicatorFound ){
        nextLine = reader.readLine();
      }
    }//end while
    return iNumChars;
  }

  /**
   * Replaces value in a single line with keyword value.
   */
  private int replaceSingleLine(String line, int iBeginValueIndex,
                                 int iValueEndIndex,
                                 Vector lines, String value,
                                 String commentStyle)
          throws KeywordExpansionException{
    String beginLine = line.substring(0, iBeginValueIndex);
    String endLine = line.substring(iValueEndIndex);
    return addValue(beginLine, endLine, value, lines, commentStyle);
  }

  /**
   * Adds the value to the lines Vector.
   */
  private int addValue(String beginLine, String endLine, String value,
                       Vector lines, String commentStyle)
          throws KeywordExpansionException{
    String expandedLine = beginLine + " " + value + endLine;
    boolean bCommentFirstLine = (beginLine.length() <= 0);
    int iTestLineLength = expandedLine.length();

    if (iTestLineLength <= LINE_MAX_LENGTH){
      lines.add(expandedLine);
    }
    else {
      Iterator itrFormattedLines = formatLines(commentStyle, expandedLine, bCommentFirstLine);

      while (itrFormattedLines.hasNext()){
        lines.add(itrFormattedLines.next());
      }
    }
    return iTestLineLength;
  }

  protected Iterator formatLines(String commentStyle, String unformattedLines,
                               boolean commentFirstLine){
    Vector lineBuilder = new Vector();
    int iStartLineIndex= 0;
    int iLineLengthMinusComment = LINE_MAX_LENGTH - commentStyle.length();
    boolean bContinue = true;
    boolean bFirstLine = true;
    while (bContinue){
      int iEndLineIndex = iStartLineIndex + iLineLengthMinusComment;
      int iSpaceIndex = unformattedLines.lastIndexOf(SPACE, iEndLineIndex);
      int iCRIndex = unformattedLines.indexOf("\r", iStartLineIndex);
      int iLFIndex = unformattedLines.indexOf("\n", iStartLineIndex);
      if (iEndLineIndex >= unformattedLines.length() || iSpaceIndex == -1){
        iSpaceIndex = unformattedLines.length();
      }
      if (iCRIndex < iSpaceIndex && iCRIndex != -1){
        //Carriage Return found in line.
        iEndLineIndex = iCRIndex;
      }
      else if (iLFIndex < iSpaceIndex && iLFIndex != -1){
        //Line Feed found in line.
        iEndLineIndex = iLFIndex;
      }
      else if (iSpaceIndex > iStartLineIndex){
        //Space found in line.
        iEndLineIndex = iSpaceIndex;
      }
      else{
        //Space, CR, and LF not found in line.
        iEndLineIndex = unformattedLines.indexOf(SPACE, iEndLineIndex);
        if (iEndLineIndex < 0){
          iEndLineIndex = unformattedLines.length();
        }//end if no space found after max characters.
      }

      String line = unformattedLines.substring(iStartLineIndex, iEndLineIndex);
      if (! bFirstLine || commentFirstLine){
        line = commentStyle + line;
      }
      bFirstLine = false;

      lineBuilder.add(line);
      iStartLineIndex = iEndLineIndex; //add one to skip the space.
      //Skip past any CR or LF.
      if (iStartLineIndex < unformattedLines.length()){
        char checkChr = unformattedLines.charAt(iStartLineIndex);
        int crCount = 0;
        int lfCount = 0;
        while (checkChr == '\r' ||
               checkChr == '\n' ||
               checkChr == ' '){
          iStartLineIndex++;
          if (checkChr == '\r'){
            crCount++;
          }
          if (checkChr == '\n'){
            lfCount++;
          }
          if ( (crCount > 1 || lfCount > 1) &&
               crCount != lfCount &&
               (checkChr == '\r' || checkChr == '\n')){
            //Means we need to add a blank line.
            lineBuilder.add(commentStyle);
          }
          if (iStartLineIndex >= unformattedLines.length()){
            break;
          }
          checkChr = unformattedLines.charAt(iStartLineIndex);
        }//end while
      }
      if (iStartLineIndex >= unformattedLines.length()){
        bContinue = false;
      }
    }//end while
    return lineBuilder.iterator();
  }

  /*
  public static void main(String[] args){
    try{
      String s = "This is a very very very long string. Check it out! This is a very very very long string. Check it out! This is a very very very long string. Check it out! \r\n\r\nThis is a very very very long string. Check it out! This is a very very very long string. Check it out! This is a very very very long string. Check it out!\r\n\r\nThis is a very very very long string. Check it out! This is a very very very long string. Check it out! ";
      System.out.println("got line. Calling formatLines");
      Iterator itr = formatLines("", s, true);
      System.out.println();
      System.out.println();
      while (itr.hasNext()){
        System.out.println(itr.next());
      }
    }
    catch(Throwable thr){
      thr.printStackTrace();
    }
  }
  */

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.