Package it.unina.seclab.jafimon

Source Code of it.unina.seclab.jafimon.CustomTranslator

package it.unina.seclab.jafimon;

import it.unina.seclab.jafimon.util.JaFiMonLogger;

import java.util.Iterator;
import java.util.TreeMap;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Modifier;
import javassist.NotFoundException;
import javassist.Translator;

/**
* Il <code>CustomTranslator</code> � il componente che viene informato del
* caricamento nella JVM di una specifica classe e su di essa effettua
* realmente le instrumentazioni di runtime se tale classe � una classe
* target. Le instrumentazioni effettuate sono quelle definite nei componenti
* {@link CustomConverter} e {@link CustomEditor} con i quali esso coopera.
* Agisce inoltre in collaborazione con {@link Monitor}.
*
* @author   Mauro Iorio
* @see Monitor
* @see CustomEditor
* @see CustomConverter
*
*/
public class CustomTranslator implements Translator {

  /**
   * La mappa in cui sono memorizzati i <code>CustomConverter</code> di
   * ciascuna classe target
   */
  private TreeMap converters;

  /**
   * La mappa in cui sono memorizzati i <code>CustomEditor</code> di
   * ciascuna classe target
   */
  private TreeMap editors;
 
  //private static final Logger logger = Logger.getRootLogger();
  private static final JaFiMonLogger logger = new JaFiMonLogger();
 
  public static final int EDITCAST       = 0;
  public static final int EDITCONSTRUCTOR   = 1;
  public static final int EDITFIELDACCESS   = 2;
  public static final int EDITHANDLER     = 3;
  public static final int EDITINSTANCEOF     = 4;
  public static final int EDITMETHODCALL     = 5;
  public static final int EDITNEWARRAY     = 6;
  public static final int EDITNEWEXPR     = 7;
 
  public CustomTranslator() {
    converters = new TreeMap();
    editors = new TreeMap();
  }
 
  /**
   * Instruments all loading classes with <code>CustomConverter</code> and
   * <code>CustomEditor</code> instrumentations
   */
  public void onLoad(ClassPool pool, String classname) throws NotFoundException, CannotCompileException {
    logger.trace("onLoad called for class " + classname);
    CtClass clas = pool.get(classname);
    if (existEditorForClass(classname))
      clas.instrument(getEditorForClass(classname));   
    if (existConverterForClass(classname))
      clas.instrument(getConverterForClass(classname));
//    if (classname.equals("it.unina.seclab.jafimon.test.DummyTest")) {
//      clas.instrument(new CustomEditor());
//    }
  }

  /**
   * Provides initialization for this <code>CustomTranslator</code>.
   */
  public void start(ClassPool pool) throws NotFoundException, CannotCompileException {
    logger.debug("CustomTranslator start");
    Iterator i = converters.values().iterator();
    while (i.hasNext()) {
      CustomConverter c = (CustomConverter) i.next();
      c.init(pool);
    }
    i = editors.values().iterator();
    while (i.hasNext()) {
      CustomEditor e = (CustomEditor) i.next();
      e.init(pool);
    }
  }

  /**
   * Returns info about the existance of a <code>CustomConverter</code> for <code>className</code>
   * @param className the class of interest
   * @return true if a <code>CustomConverter</code> exists for <code>className</code>.
   *       false otherwise.
   */
  public boolean existConverterForClass(String className) {
    return converters.containsKey(className);
  }
 
  /**
   * Returns info about the existance of a <code>CustomTranslator</code> for <code>className</code>
   * @param className the class of interest
   * @return true if a <code>CustomTranslator</code> exists for <code>className</code>.
   *       false otherwise.
   */
  public boolean existEditorForClass(String className) {
    return editors.containsKey(className);
  }
 
  /**
   * Returns the <code>CustomConverter</code> for <code>className</code>, eventually
   * creating one if it doesn't exist.
   * @param className the class of interest
   * @return a reference to the only <code>CustomConverter</code> for <code>className</code>
   */
  public CustomConverter getConverterForClass(String className) {
    if (existConverterForClass(className))
      return (CustomConverter) converters.get(className);
    else
      return null;
  }
 
  /**
   * Returns the <code>CustomEditor</code> for <code>className</code>, eventually
   * creating one if it doesn't exist.
   * @param className the class of interest
   * @return a reference to the only <code>CustomEditor</code> for <code>className</code>
   */
  public CustomEditor getEditorForClass(String className) {
    if (existEditorForClass(className))
      return (CustomEditor) editors.get(className);
    else
      return null;
  }
 
  /**
   * Explicitly creates a new <code>CustomConverter</code> for <code>className</code>
   * @param className the class of interest
   * @return a reference to the new and only <code>CustomConverter</code> for <code>className</code>
   */
  public CustomConverter newConverterForClass(String className) {
    if (existConverterForClass(className))
      return getConverterForClass(className);
    else {
      CustomConverter c = new CustomConverter();
      converters.put(className, c);
      return c;
    }
  }
 
  /**
   * Explicitly creates a new <code>CustomEditor</code> for <code>className</code>
   * @param className the class of interest
   * @return a reference to the new and only <code>CustomEditor</code> for <code>className</code>
   */
  public CustomEditor newEditorForClass(String className, ClassPool pool) {
    if (existEditorForClass(className))
      return getEditorForClass(className);
    else {
      CustomEditor e = null;
      try {
        e = (CustomEditor) pool.get("it.unina.seclab.jafimon.CustomEditor$Impl" + className.substring(className.lastIndexOf(".") + 1)).toClass().newInstance();
      } catch (InstantiationException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      } catch (IllegalAccessException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      } catch (CannotCompileException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      } catch (NotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      }
      editors.put(className, e);
      return e;
    }
  }

  /**
   * Dynamically creates a new method and inserts it into this <code>CustomEditor</code>.
   * The new method is a <i>javassist.ExprEditor.edit like</i> method. For more information
   * visit Javassist documentation
   * 
   * @param pool the javassist.ClassPool in use
   * @param className the class of interest
   * @param methodType the type of expression to edit
   * @param body the body of the new method
   * @throws CannotCompileException if the Java code is not error-free
   * @throws NotFoundException the class doesn't exist in the <code>pool</code>
   */
  public void instrumentEditor(ClassPool pool, String className, int methodType, String body) throws CannotCompileException, NotFoundException {
   
    CtClass returnType;
    String mname;
    CtClass[] exceptions;
    int modifiers;
    CtClass[] parameters;
    CtClass declaring;
    String fullClassName = "it.unina.seclab.jafimon.CustomEditor$Impl" + className.substring(className.lastIndexOf(".") + 1);

    try {
      returnType = pool.get("void");
      mname = "edit";
      exceptions = new CtClass[] { pool.get("javassist.CannotCompileException") };
      modifiers = Modifier.PUBLIC;

      // Se gia' esiste la recupero
      // altrimenti la creo nel pool
      try {
        declaring = pool.get(fullClassName);
       
      } catch(NotFoundException e) {
        declaring = pool.makeClass(fullClassName);
        declaring.setSuperclass(pool.get("it.unina.seclab.jafimon.CustomEditor"));
      }
     
      switch(methodType) {
     
      case EDITCAST:
        parameters = new CtClass[] { pool.get("javassist.expr.Cast") };
        break;

      case EDITCONSTRUCTOR:
        parameters = new CtClass[] { pool.get("javassist.expr.ConstructorCall") };
        break;

      case EDITFIELDACCESS:
        parameters = new CtClass[] { pool.get("javassist.expr.FieldAccess") };
        break;

      case EDITHANDLER:
        parameters = new CtClass[] { pool.get("javassist.expr.Handler") };
        break;

      case EDITINSTANCEOF:
        parameters = new CtClass[] { pool.get("javassist.expr.Instanceof") };
        break;

      case EDITMETHODCALL:
        parameters = new CtClass[] { pool.get("javassist.expr.MethodCall") };
        break;

      case EDITNEWARRAY:
        parameters = new CtClass[] { pool.get("javassist.expr.NewArray") };
        break;

      case EDITNEWEXPR:
        parameters = new CtClass[] { pool.get("javassist.expr.NewExpr") };
        break;

      default:
        throw new CannotCompileException("");
      }
     
      CtMethod m = CtNewMethod.make(modifiers, returnType, mname, parameters, exceptions, body, declaring);
      declaring.addMethod(m);

    } catch (Exception e) {
      throw new CannotCompileException(e);
    }
   
  }
 
}
TOP

Related Classes of it.unina.seclab.jafimon.CustomTranslator

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.