Package nhandler.conversion.jpf2jvm

Source Code of nhandler.conversion.jpf2jvm.JPF2JVMGenericConverter

package nhandler.conversion.jpf2jvm;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import gov.nasa.jpf.vm.ClassInfo;
import gov.nasa.jpf.vm.DynamicElementInfo;
import gov.nasa.jpf.vm.FieldInfo;
import gov.nasa.jpf.vm.MJIEnv;
import gov.nasa.jpf.vm.StaticElementInfo;
import nhandler.conversion.ConversionException;

/**
* This class is used to convert objects and classes from JPF to JVM. This is only
* applicable on types which are compatible between JPF and JVM, meaning that the same
* classes are used to represent them in both environments.
*
* @author Nastaran Shafiei
*/
public class JPF2JVMGenericConverter extends JPF2JVMConverter {
 
  @Override
  protected void setStaticFields(Class<?> JVMCls, StaticElementInfo sei, MJIEnv env) throws ConversionException {
    ClassInfo ci = sei.getClassInfo();
    while (JVMCls!=null) {
      Field fld[] = JVMCls.getDeclaredFields();

      for (int i = 0; i < fld.length; i++) {
        boolean isStatic = ((Modifier.toString(fld[i].getModifiers())).indexOf("static") != -1);
        boolean isFinal = ((Modifier.toString(fld[i].getModifiers())).indexOf("final") != -1);

        // Provide access to private and final fields
        fld[i].setAccessible(true);
        FieldInfo fi = sei.getFieldInfo(fld[i].getName());

        // For class only set the values of static fields
        if (fi != null && isStatic) {
          /**
           * Why we check for !(isFinal)?
           *
           * We do not set the value for "static final" fields. But we take
           * care of "non-static final" fields.
           *
           * static final fields can be initialized at the declaration time,
           * OW it MUST be initialized inside the static block. By using
           * Class.forName() the class is initialized. Since when the class
           * is initialized the static blocks are executed, the static final
           * fields of object returned by Class.forName() have already have
           * the right values and we do not need to update their value.
           *
           * Non-static final fields can be initialized at the declaration
           * time. But if the non-static field is final blank, it MUST be
           * initialized in the constructor. By using Class.newInstance()
           * the class is instantiated as if by a new expression with an
           * empty argument list. If the object represented by JPFRef
           * created using different constructor, the value of final blank
           * fields might be different when using the constructor with an
           * empty argument list. Therefore the values of non-static final
           * fields have to be set.
           */
          if (!isFinal) {
            // If the current field is of reference type
            if (fi.isReference()) {
              int fieldValueRef = sei.getFields().getReferenceValue(fi.getStorageOffset());
              Object JVMField = obtainJVMObj(fieldValueRef, env);
              try {
                fld[i].set(null, JVMField);
              } catch (IllegalArgumentException e) {
                e.printStackTrace();
              } catch (IllegalAccessException e) {
                e.printStackTrace();
              }
            }
            // If the current field is of primitive type
            else {
              try {
                Utilities.setJVMPrimitiveField(fld[i], JVMCls, sei, fi);
              } catch (IllegalAccessException e) {
                e.printStackTrace();
              }
            }
          }
        }
      }

      JVMCls = JVMCls.getSuperclass();
      ci = ci.getSuperClass();
      if(ci != null) {
        sei = ci.getStaticElementInfo();
      }
    }
  }

  @Override
  protected void setInstanceFields(Object JVMObj, DynamicElementInfo dei, MJIEnv env) throws ConversionException {
    Class<?> cls = JVMObj.getClass();
    ClassInfo JPFCl = dei.getClassInfo();

    while (cls!=null) {
      Field fld[] = cls.getDeclaredFields();

      for (int i = 0; i < fld.length; i++) {

        // It is true if the field is declared as static.
        boolean isNonStaticField = ((Modifier.toString(fld[i].getModifiers())).indexOf("static") == -1);

        // Provide access to private and final fields
        fld[i].setAccessible(true);
        FieldInfo fi = JPFCl.getInstanceField(fld[i].getName());

        if (fi != null && isNonStaticField) {
          // Field is of reference type
          if (fi.isReference()) {
            int fieldValueRef = dei.getFields().getReferenceValue(fi.getStorageOffset());
            Object JVMField = obtainJVMObj(fieldValueRef, env);

            try {
              fld[i].set(JVMObj, JVMField);
            } catch (IllegalArgumentException e) {
              e.printStackTrace();
            } catch (IllegalAccessException e) {
              e.printStackTrace();
            }
          }
          // Field is of primitive type
          else {
            try {
              Utilities.setJVMPrimitiveField(fld[i], JVMObj, dei, fi);
            } catch (IllegalAccessException e) {
              e.printStackTrace();
            }
          }
        }
      }
      cls = cls.getSuperclass();
      JPFCl = JPFCl.getSuperClass();
    }
  }

  /**
   * Returns a new JVM object instantiated from the given class
   *
   * @param cl
   *          a JVM class
   *
   * @return a new JVM object instantiated from the given class, cl
   */
  protected Object instantiateFrom (Class<?> cl) {
    Object JVMObj = null;

    if (cl == Class.class) {
      return cl;
    }

    Constructor<?> ctor = getNoArgCtor(cl);
    try {
      ctor.setAccessible(true);
      JVMObj = ctor.newInstance();
    } catch (Exception e) {
      System.out.println("Cannot instantiate from " + cl + " using ctor " + ctor);
      e.printStackTrace();
    }
    return JVMObj;
  }

  /**
   * Returns a constructor with no arguments.
   *
   * @param cl
   *          a JVM class
   *
   * @return a constructor with no arguments
   */
  protected Constructor<?> getNoArgCtor (Class<?> cl) {
    Constructor<?>[] ctors = cl.getDeclaredConstructors();
    Constructor<?> ctor = null;

    // Check if the given class has a constructor with no arguments
    for (Constructor<?> c : ctors) {
      if (c.getParameterTypes().length == 0) {
        ctor = c;
      }
    }

    if (ctor == null) {
      try {
        ctor = sun.reflect.ReflectionFactory.getReflectionFactory().newConstructorForSerialization(cl, Object.class.getConstructor());
      } catch (Exception e1) {
        System.out.println("Cannot create a default constructor to instantiate from");
        e1.printStackTrace();
      }
    }
    return ctor;
  }
}
TOP

Related Classes of nhandler.conversion.jpf2jvm.JPF2JVMGenericConverter

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.