package org.radargun.config;
import java.io.File;
import java.util.*;
import org.radargun.utils.Utils;
/**
* Instantiates stages based on annotations
*
* @author Radim Vansa <rvansa@redhat.com>
*/
public final class StageHelper {
private static Map<String, SortedMap<String, Class<? extends org.radargun.Stage>>> stagesByNamespace = new HashMap<>();
protected static final String NAMESPACE_ROOT = "urn:radargun:stages:";
static {
ClasspathScanner.scanClasspath(org.radargun.Stage.class, Stage.class, null, clazz -> {
Stage annotation = clazz.getAnnotation(Stage.class);
addStage(XmlHelper.camelCaseToDash(getStageName(clazz, annotation)), clazz);
if (!annotation.deprecatedName().equals(Stage.NO_DEPRECATED_NAME)) {
addStage(annotation.deprecatedName(), clazz);
}
});
}
private StageHelper() {}
private static void addStage(String stageName, Class<? extends org.radargun.Stage> stageClazz) {
NamespaceHelper.Coords coords = NamespaceHelper.suggestCoordinates(NAMESPACE_ROOT, stageClazz, "radargun-");
File[] codepaths = new File[] {new File(Utils.getCodePath(stageClazz))};
NamespaceHelper.registerNamespace(coords.namespace, codepaths, coords.jarMajorMinor);
addStageToNamespace(coords.namespace, stageName, stageClazz);
if (!coords.deprecatedNamespace.equals(Namespace.NO_DEPRECATED_NAME)) {
NamespaceHelper.registerNamespace(coords.deprecatedNamespace, codepaths, coords.jarMajorMinor);
addStageToNamespace(coords.deprecatedNamespace, stageName, stageClazz);
}
}
private static void addStageToNamespace(String namespace, String stageName, Class<? extends org.radargun.Stage> stageClazz) {
SortedMap<String, Class<? extends org.radargun.Stage>> stages = stagesByNamespace.get(namespace);
if (stages == null) {
stagesByNamespace.put(namespace, stages = new TreeMap<>());
}
stages.put(stageName, stageClazz);
}
public static Map<String, Map<String, Class<? extends org.radargun.Stage>>> getStages() {
return Collections.unmodifiableMap(stagesByNamespace);
}
public static Class<? extends org.radargun.Stage> getStageClassByDashedName(String namespace, String stageName) {
SortedMap<String, Class<? extends org.radargun.Stage>> stages = stagesByNamespace.get(namespace);
if (stages == null) {
throw new IllegalArgumentException("Namespace '" + namespace + "' not found. Available namespaces: " + stagesByNamespace.keySet());
}
Class<? extends org.radargun.Stage> clazz = stages.get(stageName);
if (clazz != null) {
return clazz;
} else {
throw new IllegalArgumentException("Could not find stage '" + stageName + "' in namespace '" + namespace + "'");
}
}
public static String toString(org.radargun.Stage stage) {
StringBuilder sb = new StringBuilder();
sb.append(getStageName(stage.getClass())).append(PropertyHelper.toString(stage));
return sb.toString();
}
public static boolean isStage(Class<?> stageClass) {
return stageClass != null && org.radargun.Stage.class.isAssignableFrom(stageClass)
&& stageClass.isAnnotationPresent(Stage.class);
}
public static String getStageName(Class<? extends org.radargun.Stage> clazz) {
if (clazz == null) throw new IllegalArgumentException("Class cannot be null");
Stage annotation = clazz.getAnnotation(Stage.class);
if (annotation == null) {
throw new IllegalArgumentException(clazz + " is not properly annotated.");
}
return getStageName(clazz, annotation);
}
protected static String getStageName(Class<? extends org.radargun.Stage> clazz, Stage annotation) {
String name;
if (!annotation.name().equals(Stage.CLASS_NAME_WITHOUT_STAGE)) {
name = annotation.name();
} else {
if (!clazz.getSimpleName().endsWith("Stage")) {
throw new IllegalArgumentException(clazz.getName() + " does not keep the conventional name *Stage");
}
name = clazz.getSimpleName().substring(0, clazz.getSimpleName().length() - 5);
}
return name;
}
}