Properties and XML Properties. Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/33ed792d Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/33ed792d Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/33ed792d
Branch: refs/heads/LOG4J2-1651 Commit: 33ed792daed1c31a45f8fa4fc11da72ba3c957e4 Parents: db74f85 Author: Gary Gregory <[email protected]> Authored: Sat Nov 5 00:00:39 2016 -0700 Committer: Gary Gregory <[email protected]> Committed: Sat Nov 5 00:00:39 2016 -0700 ---------------------------------------------------------------------- .../config/plugins/processor/PluginCache.java | 127 ++++++++++++++++--- .../processor/PluginCacheFormatTest.java | 12 ++ 2 files changed, 120 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/33ed792d/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCache.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCache.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCache.java index f572437..591e38d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCache.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCache.java @@ -20,14 +20,26 @@ package org.apache.logging.log4j.core.config.plugins.processor; import java.beans.XMLEncoder; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.PrintStream; +import java.io.StringReader; import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; import org.apache.logging.log4j.util.Strings; @@ -35,11 +47,25 @@ import org.apache.logging.log4j.util.Strings; * */ public class PluginCache { - + + static class SortedProperties extends Properties { + private static final long serialVersionUID = 1L; + + @Override + public synchronized Enumeration<Object> keys() { + return Collections.enumeration(new TreeSet<>(super.keySet())); + } + + @Override + public Set<String> stringPropertyNames() { + return new TreeSet<>(super.stringPropertyNames()); + } + } + public enum Format { DAT { @Override - public void writeCache(PluginCache pluginCache, OutputStream os) throws IOException { + public void writeCache(final PluginCache pluginCache, final OutputStream os) throws IOException { try (final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(os))) { // See PluginManager.readFromCacheFiles for the corresponding decoder. Format may not be changed // without breaking existing Log4j2Plugins.dat files. @@ -61,16 +87,56 @@ public class PluginCache { } } }, - + XML { @Override - public void writeCache(PluginCache pluginCache, final OutputStream os) { + public void writeCache(final PluginCache pluginCache, final OutputStream os) { try (final XMLEncoder out = new XMLEncoder(os)) { out.writeObject(pluginCache.categories); } } + }, + + PROPERTIES_XML { + + @Override + public String getExtension() { + return ".properties.xml"; + } + + @Override + public void writeCache(final PluginCache pluginCache, final OutputStream os) throws IOException { + toProperties(pluginCache).storeToXML(os, "Log4j2 plugin cache file"); + } + }, + + PROPERTIES { + @Override + public void writeCache(final PluginCache pluginCache, final OutputStream os) throws IOException { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + toProperties(pluginCache).store(baos, "Log4j2 plugin cache file"); + final String str = baos.toString("UTF-8"); + // sort + final BufferedReader r = new BufferedReader(new StringReader(str)); + String line; + final List<String> list = new ArrayList<>(); + while ((line = r.readLine()) != null) { + list.add(line); + } + Collections.sort(list); + // write sorted + final PrintStream ps = new PrintStream(os); + for (final String string : list) { + ps.println(string); + } + } + }; + public String getExtension() { + return "." + toString().toLowerCase(Locale.ROOT); + } + public abstract void writeCache(PluginCache pluginCache, final OutputStream os) throws IOException; /** @@ -82,21 +148,36 @@ public class PluginCache { * The default Formats if the input is null or empty. * @return a non-null array */ - public static Format[] parse(String formatsStr, Format... defaultFormats) { + public static Format[] parse(final String formatsStr, final Format... defaultFormats) { if (Strings.isBlank(formatsStr)) { return defaultFormats; } final String[] split = formatsStr.split("\\s*,\\s*"); - Format[] formats = new Format[split.length]; + final Format[] formats = new Format[split.length]; for (int i = 0; i < formats.length; i++) { formats[i] = Format.valueOf(split[i]); } return formats; } + + static Properties toProperties(final PluginCache pluginCache) { + final SortedProperties prop = new SortedProperties(); + for (final Entry<String, Map<String, PluginEntry>> mainEntry : pluginCache.categories.entrySet()) { + for (final Entry<String, PluginEntry> entry : mainEntry.getValue().entrySet()) { + final String key = mainEntry.getKey() + "." + entry.getKey(); + final PluginEntry pluginEntry = entry.getValue(); + prop.put(key + ".key", pluginEntry.getKey().toString()); + prop.put(key + ".classname", pluginEntry.getClassName().toString()); + prop.put(key + ".name", pluginEntry.getName().toString()); + prop.put(key + ".defer", "" + pluginEntry.isDefer()); + prop.put(key + ".printable", "" + pluginEntry.isPrintable()); + } + } + return prop; + } } - - private final Map<String, Map<String, PluginEntry>> categories = - new LinkedHashMap<>(); + + private final Map<String, Map<String, PluginEntry>> categories = new LinkedHashMap<>(); /** * Returns all categories of plugins in this cache. @@ -111,7 +192,8 @@ public class PluginCache { /** * Gets or creates a category of plugins. * - * @param category name of category to look up. + * @param category + * name of category to look up. * @return plugin mapping of names to plugin entries. */ public Map<String, PluginEntry> getCategory(final String category) { @@ -125,9 +207,12 @@ public class PluginCache { /** * Stores the plugin cache to a given OutputStream. * - * @param os destination to save cache to. - * @throws IOException if an I/O exception occurs. - * @deprecated Use {@link #writeCache(OutputStream, String)} or {@link Format#writeCache(PluginCache, OutputStream)}. + * @param os + * destination to save cache to. + * @throws IOException + * if an I/O exception occurs. + * @deprecated Use {@link #writeCache(OutputStream, String)} or + * {@link Format#writeCache(PluginCache, OutputStream)}. */ @Deprecated // NOTE: if this file format is to be changed, the filename should change and this format should still be readable @@ -138,16 +223,18 @@ public class PluginCache { /** * Stores the plugin cache to a given OutputStream. * - * @param os destination to save cache to. - * @throws IOException if an I/O exception occurs. + * @param os + * destination to save cache to. + * @throws IOException + * if an I/O exception occurs. */ // NOTE: if this file format is to be changed, the filename should change and this format should still be readable - public void writeCache(final OutputStream os, String formatsStr) throws IOException { + public void writeCache(final OutputStream os, final String formatsStr) throws IOException { if (Strings.isBlank(formatsStr)) { Format.DAT.writeCache(this, os); return; } - for (String formatStr : formatsStr.split("\\s*,\\s*")) { + for (final String formatStr : formatsStr.split("\\s*,\\s*")) { Format.valueOf(formatStr).writeCache(this, os); } } @@ -155,8 +242,10 @@ public class PluginCache { /** * Loads and merges all the Log4j plugin cache files specified. Usually, this is obtained via a ClassLoader. * - * @param resources URLs to all the desired plugin cache files to load. - * @throws IOException if an I/O exception occurs. + * @param resources + * URLs to all the desired plugin cache files to load. + * @throws IOException + * if an I/O exception occurs. */ public void loadCacheFiles(final Enumeration<URL> resources) throws IOException { categories.clear(); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/33ed792d/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCacheFormatTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCacheFormatTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCacheFormatTest.java index 2a8fe01..b7b7541 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCacheFormatTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/processor/PluginCacheFormatTest.java @@ -17,6 +17,8 @@ package org.apache.logging.log4j.core.config.plugins.processor; +import java.io.IOException; + import org.apache.logging.log4j.core.config.plugins.processor.PluginCache.Format; import org.junit.Assert; import org.junit.Test; @@ -27,4 +29,14 @@ public class PluginCacheFormatTest { public void testParseFormats() { Assert.assertArrayEquals(new Format[] { Format.DAT, Format.XML }, Format.parse("DAT,XML", Format.DAT)); } + + @Test + public void testPropertiesXml() throws IOException { + Format.PROPERTIES_XML.writeCache(PluginProcessorTest.loadCacheFiles(), System.out); + } + + @Test + public void testProperties() throws IOException { + Format.PROPERTIES.writeCache(PluginProcessorTest.loadCacheFiles(), System.out); + } }
