Package org.openiaml.verification.nusmv.oaw

Source Code of org.openiaml.verification.nusmv.oaw.NuSMVBeautifier

/**
*
*/
package org.openiaml.verification.nusmv.oaw;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.openarchitectureware.xpand2.output.FileHandle;
import org.openiaml.iacleaner.inline.InlineStringReader;
import org.openiaml.iacleaner.inline.InlineStringWriter;

/**
* @author Jevon
*
*/
public class NuSMVBeautifier implements org.openarchitectureware.xpand2.output.PostProcessor {
 
  private static IProgressMonitor monitor = null;

  public static IProgressMonitor getMonitor() {
    return monitor;
  }

  public static void setMonitor(IProgressMonitor monitor) {
    NuSMVBeautifier.monitor = monitor;
  }
 
  /**
   * Should we make a backup of the initial file in '.old'?
   *
   * @return
   */
  public boolean makeBackup() {
    return false;
  }

  /**
   * We use the IACleaner to format the file.
   *
   * @see org.openarchitectureware.xpand2.output.PostProcessor#afterClose(org.openarchitectureware.xpand2.output.FileHandle)
   * @throws RuntimeException if an IOException or CleanerException occurs while trying to format the file
   */
  public void afterClose(FileHandle file) {
    try {
      // early bail?
      if (monitor != null && monitor.isCanceled())
        throw new OperationCanceledException();
     
      // make backup?
      if (makeBackup()) {
        File backup = new File( file.getTargetFile().getAbsolutePath() + ".old" );
        FileWriter fw = new FileWriter( backup );
        fw.write( readFile(file.getTargetFile()) );
        fw.close();
      }
     
      String out = cleanNuSMV( readFile(file.getTargetFile()) );
     
      // rewrite the file
      FileWriter fw2 = new FileWriter(file.getTargetFile());
      fw2.write(out);
      fw2.close();
     
    } catch (IOException e) {
      throw new RuntimeException("[" + file.getTargetFile() + "] IO Exception during prettifier: " + e.getMessage(), e);

    } finally {
      // reset the monitor
      monitor = null;
    }
   
  }
 
  /**
   * Format the input SMV file into a cleaned output file.
   *
   * @param readFile
   * @return
   */
  public String cleanNuSMV(String input) throws IOException {
    InlineStringReader reader = new InlineStringReader(new StringReader(input)) {

      @Override
      protected void throwWarning(String message, String buffer) {
        throw new RuntimeException("Warning message: " + message);
      }
     
    };
    InlineStringWriter writer = new InlineStringWriter() {

      @Override
      protected void throwWarning(String message, String buffer) {
        throw new RuntimeException("Warning message: " + message);
      }
     
    };
   
    int c;
    int prev = -1;
    boolean inLTL = false;
    while ((c = reader.read()) != -1) {
      // skip \rs
      if (c == '\r') continue;
     
      if (Character.isWhitespace(c) /* && Character.isWhitespace(prev) */) {
        // skip
      } else if (c == '-' && reader.readAhead() == '-') {
        if (prev != -1 && !Character.isWhitespace(writer.previous())) {
          // we need to add whitespace before this comment
          writer.write(' ');
        }
       
        // a comment
        writer.write('-');
        writer.enableWordwrap(false)// disable wordwrap for comment
        while ((c = reader.read()) != -1) {
          if (c == '\r')
            continue;

          // copy comment directly
          writer.write(c);
         
          if (c == '\n')
            break;
        }
        writer.enableWordwrap(true)// re-enable wordwrap for comment
      } else if (c == 'p' && !Character.isJavaIdentifierPart(prev) && reader.has(7) && reader.readAhead(6).equals("rocess") && !Character.isJavaIdentifierPart(reader.readAhead(7).charAt(6))) {
        // 'process' keyword
        writer.write(c);
        writer.write(reader.read(6));
        writer.write(' ');
        prev = ' ';
      } else if (c == 'M' && reader.has(6) && reader.readAhead(5).equals("ODULE")) {
        // multiple modules will reduce the indent, since MODULE
        // does not have an ending statement
        if (writer.getIndentSize() != 0)
          writer.indentDecrease();
       
        // MODULE
        writer.newLine();
        writer.write(c);
        writer.write(reader.read(5));
        writer.write(' ');
      } else if (c == 'V' && reader.has(3) && reader.readAhead(2).equals("AR")) {
        // VAR
        writer.newLine();
        writer.newLine();
        writer.write(c);
        writer.write(reader.read(2));
        writer.newLine();
       
        // indent
        writer.indentIncrease();
        c = ' ';
      } else if (c == 'A' && reader.has(6) && reader.readAhead(5).equals("SSIGN")) {
        // unindent
        writer.indentDecrease();
       
        // ASSIGN
        writer.newLine();
        writer.write(c);
        writer.write(reader.read(5));
        writer.newLine();
       
        // indent
        writer.indentIncrease();
        c = ' ';
      } else if (c == 'F' && reader.has(8) && reader.readAhead(7).equals("AIRNESS")) {
        // unindent
        writer.indentDecrease();
       
        // ASSIGN
        writer.newLine();
        writer.write(c);
        writer.write(reader.read(7));
        writer.newLine();
       
        // indent
        writer.indentIncrease();
        c = ' ';
      } else if (c == 'L' && reader.has(7) && reader.readAhead(6).equals("TLSPEC")) {
        // unindent
        writer.indentDecrease();

        // LTLSPEC
        writer.newLine();
        writer.write(c);
        writer.write(reader.read(6));
        writer.newLine();
       
        // indent
        writer.indentIncrease();
        c = ' ';
       
        inLTL = true// now in LTL space
      } else if (c == 'c' && reader.has(4) && reader.readAhead(3).equals("ase") && Character.isWhitespace(reader.readAhead(4).charAt(3))) {
        // starting a case statement
        writer.write(c);
        writer.write(reader.read(3));
        writer.newLine();
       
        // indent
        writer.indentIncrease();
        c = ' ';
       
      } else if (c == 'e' &&  reader.has(4) && reader.readAhead(3).equals("sac") &&
          (Character.isWhitespace(reader.readAhead(4).charAt(3)) || reader.readAhead(4).charAt(3) == ';')) {
        // no newline, but decrease indent before writing 'esac;'
        writer.indentDecrease();

        // ending a case statement
        writer.write(c);
        writer.write(reader.read(3));
       
        c = 'c';
       
      } else if (needsWhitespaceBefore(c, reader, writer, inLTL) && !Character.isWhitespace(writer.previous())) {
        // insert whitespace
        writer.write(' ');
     
        // copy normally
        writer.write(c);
       
      } else {
         
        // copy normally
        writer.write(c);
      }
     
      if (needsNewLine(c)) {
        // write possible newline
        writer.newLineMaybe();
      } else if (needsWhitespaceAfter(c, reader, writer, inLTL)) {
        // insert whitespace
        writer.write(' ');
      }
     
      prev = c;
    }
   
    return writer.getBuffer().toString();
  }

  /**
   * @param c
   * @return
   */
  protected boolean needsNewLine(int c) {
    return (c == ';');
  }

  /**
   * @param prev
   * @return
   * @throws IOException
   */
  protected boolean needsWhitespaceAfter(int prev, InlineStringReader reader, InlineStringWriter writer, boolean inLTL) throws IOException {
    return (prev == ':' && reader.readAhead() != '=')
      || (prev == '+')
      || (prev == '-' && reader.readAhead() != '>')
      || (prev == '*')
      || (prev == '&')
      || (prev == '|')
      || (prev == '/')
      || (prev == ',')
      || (prev == '=')
      || (prev == 'd' && !Character.isJavaIdentifierPart(reader.readAhead()) && writer.getLastWritten(3).equals("mod") && Character.isWhitespace(writer.getLastWritten(4).charAt(0)))
      || (inLTL && isLTLOperator(prev))
      ;
  }

  /**
   * @param c
   * @return
   * @throws IOException
   */
  protected boolean needsWhitespaceBefore(int c, InlineStringReader reader, InlineStringWriter writer, boolean inLTL) throws IOException {
    return (c == '(' && writer.previous() != '(' && writer.previous() != '!')
      || (c == '!' && writer.previous() != '(')
      || (writer.previous() != '(' &&
          (c == '+' || c == '-' || c == '*' || c == '/' || c == '&' || c == '|'
            || (c == 'm' && reader.has(3) && reader.readAhead(2).equals("od") && !Character.isJavaIdentifierPart(reader.readAhead(3).charAt(2)))))
      || (inLTL && isLTLOperator(c) && writer.previous() != '(' && writer.previous() != '!')
      || (c == ':')
      || (c == '{')
      || (c == '=' && writer.previous() != '!' && writer.previous() != ':')
      || (c == '-' && reader.readAhead() == '>');
  }

  protected boolean isLTLOperator(int prev) {
    return (prev == 'F' || prev == 'G' || prev == 'X' || prev == 'U' || prev == 'R' || prev == 'W');
  }
 
  /**
   * Format the input SMV file into a cleaned output file.
   *
   * @param readFile
   * @return
   * @throws IOException
   */
  public String cleanNuSMV(File readFile) throws IOException {
    return cleanNuSMV(readFile(readFile));
  }

  /* (non-Javadoc)
   * @see org.openarchitectureware.xpand2.output.PostProcessor#beforeWriteAndClose(org.openarchitectureware.xpand2.output.FileHandle)
   */
  public void beforeWriteAndClose(FileHandle file) {
    // ignore 
  }


  /**
   * Read in a file into a string.
   *
   * @throws IOException if an IO exception occurs
   */
  public static String readFile(File sourceFile) throws IOException {
    return readFile(new FileReader(sourceFile));
  }
 
  /**
   * Read in an InputStream into a string.
   *
   * @throws IOException if an IO exception occurs
   */
  public static String readFile(InputStream stream) throws IOException {
    return readFile(new InputStreamReader(stream));
  }
 
  /**
   * Read in a Reader into a string.
   *
   * @throws IOException if an IO exception occurs
   */
  public static String readFile(Reader sourceReader) throws IOException {
    int bufSize = 128;
    StringBuffer sb = new StringBuffer();
    BufferedReader reader = new BufferedReader(sourceReader, bufSize);
   
    char[] chars = new char[bufSize];
    int numRead = 0;
    while ((numRead = reader.read(chars)) != -1) {
      sb.append(chars, 0, numRead);
    }

    reader.close();
    return sb.toString();
  }
 
}
TOP

Related Classes of org.openiaml.verification.nusmv.oaw.NuSMVBeautifier

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.