Search in sources :

Example 1 with PluginEntry

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;
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) DecimalFormat(java.text.DecimalFormat) ArrayList(java.util.ArrayList) PluginEntry(org.apache.logging.log4j.plugins.processor.PluginEntry) IOException(java.io.IOException) URL(java.net.URL) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) PluginCache(org.apache.logging.log4j.plugins.processor.PluginCache) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 2 with PluginEntry

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;
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) DecimalFormat(java.text.DecimalFormat) PluginEntry(org.apache.logging.log4j.plugins.processor.PluginEntry) PluginAliases(org.apache.logging.log4j.plugins.PluginAliases) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) Plugin(org.apache.logging.log4j.plugins.Plugin)

Example 3 with PluginEntry

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();
    });
}
Also used : PluginService(org.apache.logging.log4j.plugins.processor.PluginService) DecimalFormat(java.text.DecimalFormat) PluginEntry(org.apache.logging.log4j.plugins.processor.PluginEntry)

Example 4 with PluginEntry

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("}");
    }
}
Also used : PluginEntry(org.apache.logging.log4j.plugins.processor.PluginEntry) PrintWriter(java.io.PrintWriter)

Example 5 with PluginEntry

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;
}
Also used : Messager(javax.annotation.processing.Messager) ArrayList(java.util.ArrayList) PluginEntry(org.apache.logging.log4j.plugins.processor.PluginEntry) LoggingException(org.apache.logging.log4j.LoggingException) IOException(java.io.IOException)

Aggregations

PluginEntry (org.apache.logging.log4j.plugins.processor.PluginEntry)9 DecimalFormat (java.text.DecimalFormat)3 ArrayList (java.util.ArrayList)3 Plugin (org.apache.logging.log4j.plugins.Plugin)3 PluginType (org.apache.logging.log4j.plugins.util.PluginType)3 Test (org.junit.Test)3 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 PluginAliases (org.apache.logging.log4j.plugins.PluginAliases)2 PrintWriter (java.io.PrintWriter)1 URL (java.net.URL)1 Collection (java.util.Collection)1 Map (java.util.Map)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 Messager (javax.annotation.processing.Messager)1 Element (javax.lang.model.element.Element)1 TypeElement (javax.lang.model.element.TypeElement)1