Package eclipse.themes.darker.core

Source Code of eclipse.themes.darker.core.DarkerWeavingHook

package eclipse.themes.darker.core;

import java.io.Closeable;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import org.osgi.framework.hooks.weaving.WeavingHook;
import org.osgi.framework.hooks.weaving.WovenClass;
import org.osgi.service.component.ComponentContext;

import static org.objectweb.asm.Opcodes.*;

/**
* @author Jin Mingjian(jin.phd@gmail.com)
*
*/
public class DarkerWeavingHook implements WeavingHook {

  private static String WEAVINGHOOK_STORE = "weavinghookstore";

  private static int    weavingEnabled    = 0;

  protected void activate(ComponentContext context) {
    File hookingStore = context.getBundleContext().getDataFile(
        WEAVINGHOOK_STORE);
    FileReader reader = null;
    try {
      if (!hookingStore.exists())
        hookingStore.createNewFile();
     
      reader = new FileReader(hookingStore);
      weavingEnabled = reader.read();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      close(reader);
    }
  }

  protected void deactivate(ComponentContext context) {
    File hookingStore = context.getBundleContext().getDataFile(
        WEAVINGHOOK_STORE);
    FileWriter writer = null;
    try {
      writer = new FileWriter(hookingStore);
      writer.write(weavingEnabled);
      writer.flush();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      close(writer);
    }
  }

  private static void close(Closeable c) {
    try {
      if (c != null)
        c.close();
    } catch (IOException e) {
      // TODO
    }
  }

  @Override
  public void weave(WovenClass wovenClass) {
    if (weavingEnabled==0) return;
   
    try {
      String className = wovenClass.getClassName();
      if (className.equals("org.eclipse.swt.custom.CLabel")) {
        transform(wovenClass);
      }
    } catch (ClassCircularityError cce) {
      // TODO
    }
  }

  public void transform(WovenClass wovenClass) {
    byte[] bytes = wovenClass.getBytes();

    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS
        | ClassWriter.COMPUTE_FRAMES);
    cr.accept(cw, 0);

    Method md = Method
        .getMethod("org.eclipse.swt.graphics.Color getForeground ()");
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, md.getName(),
        md.getDescriptor(), null, null);
   
    final GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, md, mv);
    final Label LABEL_SKIP_CALL_TO_SUPER = new Label();
    final Label LABEL_LOOP_CMP = new Label();
    final Label LABEL_LOOP_START = new Label();
   
    mg.newInstance(Type.getType(Exception.class));
    mg.dup();
    mg.invokeConstructor(Type.getType(Exception.class),
        Method.getMethod("void <init> ()"));
    mg.invokeVirtual(Type.getType(Exception.class),
        Method.getMethod("StackTraceElement[] getStackTrace ()"));
    mg.storeLocal(1,Type.getType(StackTraceElement[].class));

    mg.push(10);
    mg.storeLocal(2,Type.getType(int.class));
   
    mg.goTo(LABEL_LOOP_CMP);

    mg.mark(LABEL_LOOP_START);
    mg.loadLocal(1);
    mg.loadLocal(2);
    mg.arrayLoad(Type.getType(StackTraceElement.class));
    mg.invokeVirtual(Type.getType(StackTraceElement.class),
        Method.getMethod("String getClassName ()"));
    mg.push("Dialog");
    mg.invokeVirtual(Type.getType(String.class),
        Method.getMethod("int indexOf (String)"));
    mg.push(-1);
    mg.ifICmp(GeneratorAdapter.EQ, LABEL_SKIP_CALL_TO_SUPER);
//    //XXX: DEBUG
//    mg.getStatic(Type.getType(System.class), "out", Type.getType(java.io.PrintStream.class));
//    mg.push("2");
//    mg.invokeVirtual(Type.getType(java.io.PrintStream.class), Method.getMethod("void println (String)"));
//    //XXX: DEBUG
    mg.loadThis();
    mg.invokeConstructor(Type.getType("Lorg/eclipse/swt/widgets/Control;"),
        Method.getMethod("org.eclipse.swt.graphics.Color getForeground ()"));
    mg.returnValue();
   
    mg.mark(LABEL_SKIP_CALL_TO_SUPER);
    mg.iinc(2, 1);
   
    mg.mark(LABEL_LOOP_CMP);
    mg.loadLocal(2);
    mg.loadLocal(1);
    mg.arrayLength();
    mg.ifICmp(GeneratorAdapter.LT, LABEL_LOOP_START);
   
    mg.loadThis();
    mg.invokeVirtual(Type.getType("Lorg/eclipse/swt/custom/CLabel;"),
        Method.getMethod("org.eclipse.swt.widgets.Display getDisplay ()"));
    mg.push(1);
    mg.invokeVirtual(Type.getType("Lorg/eclipse/swt/widgets/Display;"),
        Method.getMethod("org.eclipse.swt.graphics.Color getSystemColor (int)"));
    mg.returnValue();
   
    mg.endMethod();
    cw.visitEnd();

    wovenClass.setBytes(cw.toByteArray());
  }

  public static boolean hasWeavingEnabled() {
    return weavingEnabled == 1 ? true : false;
  }

  public static void enableWeaving() {
    weavingEnabled = 1;
  }

  public static void disableWeaving() {
    weavingEnabled = 0;
  }
}
TOP

Related Classes of eclipse.themes.darker.core.DarkerWeavingHook

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.