All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jvmbytes.spy.inject.SpyInjector Maven / Gradle / Ivy

The newest version!
package com.jvmbytes.spy.inject;

import com.jvmbytes.agent.inst.InstLoader;
import com.jvmbytes.filter.manager.ClassDataSource;
import com.jvmbytes.filter.matcher.Matcher;
import com.jvmbytes.spy.enhance.weaver.EventListenerHandlers;
import com.jvmbytes.spy.event.EventType;
import com.jvmbytes.spy.inject.transform.SpyTransformer;
import com.jvmbytes.spy.listener.EventListener;
import com.jvmbytes.spy.util.SpyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wongoo
 */
public final class SpyInjector {
    private static final Logger logger = LoggerFactory.getLogger(SpyInjector.class);

    private static Instrumentation inst;

    private static ClassDataSource classDataSource;

    public static final String DEFAULT_NAMESPACE = "default";

    private static Map transformers
            = new ConcurrentHashMap(8);

    static {
        try {
            setInst(InstLoader.loadInst());
        } catch (Exception e) {
        }
    }

    public static void setInst(Instrumentation inst) {
        SpyInjector.inst = inst;
        SpyInjector.classDataSource = new ClassDataSource(inst, true);
    }

    private static void checkInst() throws Exception {
        if (inst == null) {
            throw new Exception("Instrumentation not initialized");
        }
    }

    public static int inject(Matcher matcher, EventType[] types, EventListener listener) throws Exception {
        return inject(DEFAULT_NAMESPACE, matcher, types, listener);
    }

    public static int inject(String namespace, Matcher matcher, EventType[] types, EventListener listener) throws Exception {
        checkInst();

        SpyUtils.init(namespace);

        SpyTransformer transformer = new SpyTransformer(namespace, matcher, types, listener);

        transformers.put(transformer.getListenerId(), transformer);

        EventListenerHandlers.getSingleton().active(transformer.getListenerId(), listener, types);

        inst.addTransformer(transformer, true);

        retransform(matcher);

        return transformer.getListenerId();
    }

    public static void remove(int id) throws Exception {
        checkInst();

        SpyTransformer transformer = transformers.remove(id);
        if (transformer != null) {
            inst.removeTransformer(transformer);
            EventListenerHandlers.getSingleton().frozen(transformer.getListenerId());
            retransform(transformer.getMatcher());
        }
    }

    private static void retransform(Matcher matcher) {
        List> classes = classDataSource.find(matcher);
        if (classes.size() > 0) {
            try {
                inst.retransformClasses(classes.toArray(new Class[0]));
            } catch (UnmodifiableClassException e) {
                logger.debug("retransform error: {},{}", e.getClass().getName(), e.getMessage());
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy