use of org.apache.logging.log4j.plugins.processor.PluginEntry in project logging-log4j2 by apache.
the class PluginRegistry method decodeCacheFiles.
private Map<String, List<PluginType<?>>> decodeCacheFiles(final ClassLoader loader) {
final long startTime = System.nanoTime();
final PluginCache cache = new PluginCache();
try {
final Enumeration<URL> resources = loader.getResources(PluginManager.PLUGIN_CACHE_FILE);
if (resources == null) {
LOGGER.info("Plugin preloads not available from class loader {}", loader);
} else {
cache.loadCacheFiles(resources);
}
} catch (final IOException ioe) {
LOGGER.warn("Unable to preload plugins", ioe);
}
final Map<String, List<PluginType<?>>> newPluginsByCategory = new HashMap<>();
int pluginCount = 0;
for (final Map.Entry<String, Map<String, PluginEntry>> outer : cache.getAllCategories().entrySet()) {
final String categoryLowerCase = outer.getKey();
final List<PluginType<?>> types = new ArrayList<>(outer.getValue().size());
newPluginsByCategory.put(categoryLowerCase, types);
for (final Map.Entry<String, PluginEntry> inner : outer.getValue().entrySet()) {
final PluginEntry entry = inner.getValue();
final String className = entry.getClassName();
final PluginType<?> type = new PluginType<>(entry, loader);
types.add(type);
++pluginCount;
}
}
final int numPlugins = pluginCount;
LOGGER.debug(() -> {
final long endTime = System.nanoTime();
StringBuilder sb = new StringBuilder("Took ");
final DecimalFormat numFormat = new DecimalFormat("#0.000000");
sb.append(numFormat.format((endTime - startTime) * 1e-9));
sb.append(" seconds to load ").append(numPlugins);
sb.append(" plugins from ").append(loader);
return sb.toString();
});
return newPluginsByCategory;
}
use of org.apache.logging.log4j.plugins.processor.PluginEntry in project logging-log4j2 by apache.
the class PluginRegistry method loadFromPackage.
/**
* Load plugin types from a package.
* @param pkg The package name.
* @return A Map of the lists of plugin types organized by category.
* @since 2.1
*/
public Map<String, List<PluginType<?>>> loadFromPackage(final String pkg) {
if (Strings.isBlank(pkg)) {
// happens when splitting an empty string
return Collections.emptyMap();
}
Map<String, List<PluginType<?>>> existing = pluginsByCategoryByPackage.get(pkg);
if (existing != null) {
// already loaded this package
return existing;
}
final long startTime = System.nanoTime();
final ResolverUtil resolver = new ResolverUtil();
final ClassLoader classLoader = LoaderUtil.getClassLoader();
if (classLoader != null) {
resolver.setClassLoader(classLoader);
}
resolver.findInPackage(new PluginTest(), pkg);
final Map<String, List<PluginType<?>>> newPluginsByCategory = new HashMap<>();
for (final Class<?> clazz : resolver.getClasses()) {
final Plugin plugin = clazz.getAnnotation(Plugin.class);
final String categoryLowerCase = plugin.category().toLowerCase();
List<PluginType<?>> list = newPluginsByCategory.computeIfAbsent(categoryLowerCase, k -> new ArrayList<>());
final PluginEntry mainEntry = new PluginEntry();
final String mainElementName = plugin.elementType().equals(Plugin.EMPTY) ? plugin.name() : plugin.elementType();
mainEntry.setKey(plugin.name().toLowerCase());
mainEntry.setName(plugin.name());
mainEntry.setCategory(plugin.category());
mainEntry.setClassName(clazz.getName());
mainEntry.setPrintable(plugin.printObject());
mainEntry.setDefer(plugin.deferChildren());
final PluginType<?> mainType = new PluginType<>(mainEntry, clazz, mainElementName);
list.add(mainType);
final PluginAliases pluginAliases = clazz.getAnnotation(PluginAliases.class);
if (pluginAliases != null) {
for (final String alias : pluginAliases.value()) {
final PluginEntry aliasEntry = new PluginEntry();
final String aliasElementName = plugin.elementType().equals(Plugin.EMPTY) ? alias.trim() : plugin.elementType();
aliasEntry.setKey(alias.trim().toLowerCase());
aliasEntry.setName(plugin.name());
aliasEntry.setCategory(plugin.category());
aliasEntry.setClassName(clazz.getName());
aliasEntry.setPrintable(plugin.printObject());
aliasEntry.setDefer(plugin.deferChildren());
final PluginType<?> aliasType = new PluginType<>(aliasEntry, clazz, aliasElementName);
list.add(aliasType);
}
}
}
LOGGER.debug(() -> {
final long endTime = System.nanoTime();
StringBuilder sb = new StringBuilder("Took ");
final DecimalFormat numFormat = new DecimalFormat("#0.000000");
sb.append(numFormat.format((endTime - startTime) * 1e-9));
sb.append(" seconds to load ").append(resolver.getClasses().size());
sb.append(" plugins from package ").append(pkg);
return sb.toString();
});
// Note multiple threads could be calling this method concurrently. Both will do the work,
// but only one will be allowed to store the result in the outer map.
// Return the inner map produced by whichever thread won the race, so all callers will get the same result.
existing = pluginsByCategoryByPackage.putIfAbsent(pkg, newPluginsByCategory);
if (existing != null) {
return existing;
}
return newPluginsByCategory;
}
use of org.apache.logging.log4j.plugins.processor.PluginEntry in project logging-log4j2 by apache.
the class PluginRegistry method loadPlugins.
/**
* Load plugins from a specific ClassLoader.
* @param classLoader The ClassLoader.
* @param map The Map of the list of plugin types organized by category.
* @since 3.0
*/
public void loadPlugins(ClassLoader classLoader, Map<String, List<PluginType<?>>> map) {
final long startTime = System.nanoTime();
final ServiceLoader<PluginService> serviceLoader = ServiceLoader.load(PluginService.class, classLoader);
int pluginCount = 0;
for (final PluginService pluginService : serviceLoader) {
PluginEntry[] entries = pluginService.getEntries();
for (PluginEntry entry : entries) {
final PluginType<?> type = new PluginType<>(entry, classLoader);
String category = entry.getCategory().toLowerCase();
if (!map.containsKey(category)) {
map.put(category, new ArrayList<>());
}
List<PluginType<?>> list = map.get(category);
list.add(type);
++pluginCount;
}
}
final int numPlugins = pluginCount;
LOGGER.debug(() -> {
final long endTime = System.nanoTime();
StringBuilder sb = new StringBuilder("Took ");
final DecimalFormat numFormat = new DecimalFormat("#0.000000");
sb.append(numFormat.format((endTime - startTime) * 1e-9));
sb.append(" seconds to load ").append(numPlugins);
sb.append(" plugins from ").append(classLoader);
return sb.toString();
});
}
use of org.apache.logging.log4j.plugins.processor.PluginEntry in project logging-log4j2 by apache.
the class PluginProcessor method writeClassFile.
private void writeClassFile(String pkg, List<PluginEntry> list) {
String fqcn = createFqcn(pkg);
try (final PrintWriter writer = createSourceFile(fqcn)) {
writer.println("package " + pkg + ".plugins;");
writer.println("");
writer.println("import org.apache.logging.log4j.plugins.processor.PluginEntry;");
writer.println("import org.apache.logging.log4j.plugins.processor.PluginService;");
writer.println("");
writer.println("public class Log4jPlugins extends PluginService {");
writer.println("");
writer.println(" private static PluginEntry[] entries = new PluginEntry[] {");
StringBuilder sb = new StringBuilder();
int max = list.size() - 1;
for (int i = 0; i < list.size(); ++i) {
PluginEntry entry = list.get(i);
sb.append(" ").append("new PluginEntry(\"");
sb.append(entry.getKey()).append("\", \"");
sb.append(entry.getClassName()).append("\", \"");
sb.append(entry.getName()).append("\", ");
sb.append(entry.isPrintable()).append(", ");
sb.append(entry.isDefer()).append(", \"");
sb.append(entry.getCategory()).append("\")");
if (i < max) {
sb.append(",");
}
writer.println(sb.toString());
sb.setLength(0);
}
writer.println(" };");
writer.println(" @Override");
writer.println(" public PluginEntry[] getEntries() { return entries;}");
writer.println("}");
}
}
use of org.apache.logging.log4j.plugins.processor.PluginEntry in project logging-log4j2 by apache.
the class PluginProcessor method process.
@Override
public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
Map<String, String> options = processingEnv.getOptions();
String packageName = options.get("pluginPackage");
Messager messager = processingEnv.getMessager();
messager.printMessage(Kind.NOTE, "Processing Log4j annotations");
try {
final Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Plugin.class);
if (elements.isEmpty()) {
messager.printMessage(Kind.NOTE, "No elements to process");
return false;
}
messager.printMessage(Kind.NOTE, "Retrieved " + elements.size() + " Plugin elements");
List<PluginEntry> list = new ArrayList<>();
packageName = collectPlugins(packageName, elements, list);
writeClassFile(packageName, list);
writeServiceFile(packageName);
messager.printMessage(Kind.NOTE, "Annotations processed");
} catch (final Exception ex) {
error(ex.getMessage());
}
return false;
}
Aggregations