/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * JFlex 1.4.3                                                             *
 * Copyright (C) 1998-2009  Gerwin Klein <lsf@jflex.de>                    *
 * All rights reserved.                                                    *
 *                                                                         *
 * This program is free software; you can redistribute it and/or modify    *
 * it under the terms of the GNU General Public License. See the file      *
 * COPYRIGHT for more information.                                         *
 *                                                                         *
 * This program 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 General Public License for more details.                            *
 *                                                                         *
 * You should have received a copy of the GNU General Public License along *
 * with this program; if not, write to the Free Software Foundation, Inc., *
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                 *
 *                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package JFlex;

import java.io.*;
import java.net.URL;
import java.util.Vector;


/**
 * This class stores the skeleton of generated scanners.
 *
 * The skeleton consists of several parts that can be emitted to
 * a file. Usually there is a portion of generated code
 * (produced in class Emitter) between every two parts of skeleton code.
 *
 * There is a static part (the skeleton code) and state based iterator
 * part to this class. The iterator part is used to emit consecutive skeleton
 * sections to some <code>PrintWriter</code>. 
 *
 * @see JFlex.Emitter
 *
 * @author Gerwin Klein
 * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $ 
 */
public class Skeleton {
  
  /** location of default skeleton */
  static final private String DEFAULT_LOC = "JFlex/skeleton.default"; //$NON-NLS-1$
  
  /** expected number of sections in the skeleton file */
  static final private int size = 21;

  /** platform specific newline */
  static final private String NL = System.getProperty("line.separator");  //$NON-NLS-1$

  /** The skeleton */  
  public static String line[];
  
  /** initialization */   
  static { readDefault(); }  
  
  // the state based, iterator part of Skeleton:

  /**
   * The current part of the skeleton (an index of nextStop[])
   */
  private int pos;  
  
  /**
   * The writer to write the skeleton-parts to
   */
  private PrintWriter out;


  /**
   * Creates a new skeleton (iterator) instance. 
   *
   * @param   out  the writer to write the skeleton-parts to
   */
  public Skeleton(PrintWriter out) {
    this.out = out;
  }


  /**
   * Emits the next part of the skeleton
   */
  public void emitNext() {
    out.print( line[pos++] );
  }


  /**
   * Make the skeleton private.
   *
   * Replaces all occurences of " public " in the skeleton with " private ". 
   */
  public static void makePrivate() {
    for (int i=0; i < line.length; i++) {
      line[i] = replace(" public ", " private ", line[i]);   //$NON-NLS-1$ //$NON-NLS-2$
    }
  } 


  /**
   * Reads an external skeleton file for later use with this class.
   * 
   * @param skeletonFile  the file to read (must be != null and readable)
   */
  public static void readSkelFile(File skeletonFile) {
    if (skeletonFile == null)
      throw new IllegalArgumentException("Skeleton file must not be null"); //$NON-NLS-1$

    if (!skeletonFile.isFile() || !skeletonFile.canRead()) {
      Out.error(ErrorMessages.CANNOT_READ_SKEL, skeletonFile.toString()); 
      throw new GeneratorException();
    }

    Out.println(ErrorMessages.READING_SKEL, skeletonFile.toString());

    try {
      BufferedReader reader = new BufferedReader(new FileReader(skeletonFile));
      readSkel(reader);
    }
    catch (IOException e) {
      Out.error(ErrorMessages.SKEL_IO_ERROR); 
      throw new GeneratorException();
    }
  }


  /**
   * Reads an external skeleton file from a BufferedReader.
   * 
   * @param  reader             the reader to read from (must be != null)
   * @throws IOException        if an IO error occurs
   * @throws GeneratorException if the number of skeleton sections does not match 
   */
  public static void readSkel(BufferedReader reader) throws IOException {
    Vector lines = new Vector();
    StringBuffer section = new StringBuffer();

    String ln;
    while ((ln = reader.readLine()) != null) {
      if (ln.startsWith("---")) { //$NON-NLS-1$
        lines.addElement(section.toString());
        section.setLength(0);
      } else {
        section.append(ln);
        section.append(NL);
      }
    }

    if (section.length() > 0)
      lines.addElement(section.toString());

    if (lines.size() != size) {
      Out.error(ErrorMessages.WRONG_SKELETON);
      throw new GeneratorException();
    }

    line = new String[size];
    for (int i = 0; i < size; i++)
      line[i] = (String) lines.elementAt(i);
  }
  
  /**
   * Replaces a with b in c.
   * 
   * @param a  the String to be replaced
   * @param b  the replacement
   * @param c  the String in which to replace a by b
   * @return a String object with a replaced by b in c 
   */
  public static String replace(String a, String b, String c) {
    StringBuffer result = new StringBuffer(c.length());
    int i = 0;
    int j = c.indexOf(a);
    
    while (j >= i) {
      result.append(c.substring(i,j));
      result.append(b);
      i = j+a.length();
      j = c.indexOf(a,i);
    }

    result.append(c.substring(i,c.length()));
    
    return result.toString();
  }

  
  /**
   * (Re)load the default skeleton. Looks in the current system class path.   
   */
  public static void readDefault() {
    ClassLoader l = Skeleton.class.getClassLoader();
    URL url;
    
    /* Try to load from same class loader as this class.
     * Should work, but does not on OS/2 JDK 1.1.8 (see bug 1065521).
     * Use system class loader in this case.
     */
    if (l != null) {
      url = l.getResource(DEFAULT_LOC); 
    }
    else {
      url = ClassLoader.getSystemResource(DEFAULT_LOC); 
    }

    if (url == null) {
      Out.error(ErrorMessages.SKEL_IO_ERROR_DEFAULT);
      throw new GeneratorException();    
    }
    
    try {
      InputStreamReader reader = new InputStreamReader(url.openStream());
      readSkel(new BufferedReader(reader)); 
    } catch (IOException e) {
      Out.error(ErrorMessages.SKEL_IO_ERROR_DEFAULT); 
      throw new GeneratorException();
    }
  }
}
