/*
* Copyright (c) 2009-2011 Clark & Parsia, LLC. <http://www.clarkparsia.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.clarkparsia.empire.spi;
import com.google.common.collect.Sets;
import java.lang.instrument.Instrumentation;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Set;
/**
* <p>Simple -javaagent compatible instrumentor. Provides a premain implementation which grabs a handle to the JVM {@link Instrumentation} and keeps a reference
* to it for use later on.</p>
*
* @author Michael Grove
* @since 0.7
* @version 0.7
*/
public final class Instrumentor {
/**
* The JVM instrumentation
*/
private static Instrumentation INSTANCE;
/**
* Return the JVM instrumentation
* @return the instrumentation or null if this was not used as the java agent
*/
public static Instrumentation instrumentation() {
return INSTANCE;
}
/**
* Premain method for use with -javaagent.
* @param theAgentArgs the cmd line args
* @param theJVMInst the JVM instrumentation
*/
public static void premain(final String theAgentArgs, final Instrumentation theJVMInst) {
INSTANCE = theJVMInst;
}
/**
* Return all the classes loaded into the JVM which extend from the provided class
* @param theClass the class
* @param <T> the base class type
* @return all the classes extending from the parameter. An empty collection will be returned if this java agent is not installed
*/
public static <T> Collection<Class<? extends T>> instancesOf(Class<T> theClass) {
Instrumentation aInst = instrumentation();
if (aInst == null) {
return Sets.newHashSet();
}
Set<Class<? extends T>> aClasses = Sets.newHashSet();
for (Class<?> aCls : aInst.getAllLoadedClasses()) {
if (theClass.isAssignableFrom(aCls)) {
aClasses.add((Class<T>) aCls);
}
}
return aClasses;
}
/**
* Return all the classes which have the given annotation applied to them
* @param theAnnotation the annotation
* @return the classes with the annotation. An empty collection will be returned if this java agent is not installed
*/
public static Collection<Class<?>> annotatedWith(Class<? extends Annotation> theAnnotation) {
Instrumentation aInst = instrumentation();
if (aInst == null) {
return Sets.newHashSet();
}
Set<Class<?>> aClasses = Sets.newHashSet();
for (Class<?> aCls : aInst.getAllLoadedClasses()) {
if (aCls.getAnnotation(theAnnotation) != null) {
aClasses.add(aCls);
}
}
return aClasses;
}
/**
* Return whether or not the JVM instrumentation has been initialized via the JVM agent
* @return true if initialized, false otherwise
*/
public static boolean isInitialized() {
return INSTANCE != null;
}
}