Aren't there escaping rules in properties files, too? Might not be relevant for this cache file, though.
On 6 November 2016 at 00:36, Remko Popma <remko.po...@gmail.com> wrote: > But that's trivially implemented with a BiConsumer or TriConsumer: > > StringMap map = getMap(); > map.forEach(k, v, out -> { > out.print(k); > out.print('='); > out.println(v); > }); > > Sent from my iPhone > > On 6 Nov 2016, at 13:19, Gary Gregory <garydgreg...@gmail.com> wrote: > > But a SortedArrayStringMap is not a Property, so it cannot write out a > property file. > > Gary > > On Sat, Nov 5, 2016 at 8:24 PM, Remko Popma <remko.po...@gmail.com> wrote: > >> FYI, you could also use a SortedArrayStringMap for that purpose. >> >> Sent from my iPhone >> >> > On 6 Nov 2016, at 11:47, ggreg...@apache.org wrote: >> > >> > Repository: logging-log4j2 >> > Updated Branches: >> > refs/heads/LOG4J2-1651 5465f5cf3 -> 5cce8c115 >> > >> > >> > Refactor reading cache files. Extract out SortedProperties class. >> > >> > Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo >> > Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit >> /5cce8c11 >> > Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/5 >> cce8c11 >> > Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/5 >> cce8c11 >> > >> > Branch: refs/heads/LOG4J2-1651 >> > Commit: 5cce8c11560954f283a7a5a721b718104beebd31 >> > Parents: 5465f5c >> > Author: Gary Gregory <ggreg...@apache.org> >> > Authored: Sat Nov 5 19:47:30 2016 -0700 >> > Committer: Gary Gregory <ggreg...@apache.org> >> > Committed: Sat Nov 5 19:47:30 2016 -0700 >> > >> > ---------------------------------------------------------------------- >> > .../config/plugins/processor/PluginCache.java | 195 >> +++++++++++-------- >> > .../config/plugins/util/PluginRegistry.java | 1 + >> > .../log4j/core/util/SortedProperties.java | 47 +++++ >> > 3 files changed, 160 insertions(+), 83 deletions(-) >> > ---------------------------------------------------------------------- >> > >> > >> > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5 >> cce8c11/log4j-core/src/main/java/org/apache/logging/log4j/co >> re/config/plugins/processor/PluginCache.java >> > ---------------------------------------------------------------------- >> > diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/con >> fig/plugins/processor/PluginCache.java b/log4j-core/src/main/java/org >> /apache/logging/log4j/core/config/plugins/processor/PluginCache.java >> > index 9f73fb3..912f247 100644 >> > --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con >> fig/plugins/processor/PluginCache.java >> > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con >> fig/plugins/processor/PluginCache.java >> > @@ -17,6 +17,7 @@ >> > >> > package org.apache.logging.log4j.core.config.plugins.processor; >> > >> > +import java.beans.XMLDecoder; >> > import java.beans.XMLEncoder; >> > import java.io.BufferedInputStream; >> > import java.io.BufferedOutputStream; >> > @@ -38,9 +39,8 @@ 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.core.util.SortedProperties; >> > import org.apache.logging.log4j.util.Strings; >> > >> > /** >> > @@ -48,23 +48,34 @@ 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 loadCacheFiles(final PluginCache pluginCache, >> final URL url) throws IOException { >> > + try (final DataInputStream in = new >> DataInputStream(new BufferedInputStream(url.openStream()))) { >> > + final int count = in.readInt(); >> > + for (int i = 0; i < count; i++) { >> > + final String category = in.readUTF(); >> > + final Map<String, PluginEntry> m = >> pluginCache.getCategory(category); >> > + final int entries = in.readInt(); >> > + for (int j = 0; j < entries; j++) { >> > + final PluginEntry entry = new >> PluginEntry(); >> > + entry.setKey(in.readUTF()); >> > + entry.setClassName(in.readUTF()); >> > + entry.setName(in.readUTF()); >> > + entry.setPrintable(in.readBoolean()); >> > + entry.setDefer(in.readBoolean()); >> > + entry.setCategory(category); >> > + if (!m.containsKey(entry.getKey())) { >> > + m.put(entry.getKey(), entry); >> > + } >> > + } >> > + } >> > + } >> > + } >> > + >> > + @Override >> > 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 >> > @@ -88,28 +99,13 @@ public class PluginCache { >> > } >> > }, >> > >> > - XML { >> > - @Override >> > - public void writeCache(final PluginCache pluginCache, >> final OutputStream os) { >> > - try (final XMLEncoder out = new XMLEncoder(os)) { >> > - out.writeObject(pluginCache.categories); >> > - } >> > - } >> > - }, >> > - >> > - PROPERTIES_XML { >> > + PROPERTIES { >> > @Override >> > - public String getExtension() { >> > - return ".properties.xml"; >> > - } >> > + public void loadCacheFiles(final PluginCache pluginCache, >> final URL url) throws IOException { >> > + // TODO Auto-generated method stub >> > >> > - @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(); >> > @@ -130,13 +126,43 @@ public class PluginCache { >> > } >> > } >> > >> > - }; >> > + }, >> > >> > - public String getExtension() { >> > - return "." + toString().toLowerCase(Locale.ROOT); >> > - } >> > + PROPERTIES_XML { >> > + @Override >> > + public String getExtension() { >> > + return ".properties.xml"; >> > + } >> > + >> > + @Override >> > + public void loadCacheFiles(final PluginCache pluginCache, >> final URL url) throws IOException { >> > + // TODO Auto-generated method stub >> > + >> > + } >> > + >> > + @Override >> > + public void writeCache(final PluginCache pluginCache, >> final OutputStream os) throws IOException { >> > + toProperties(pluginCache).storeToXML(os, "Log4j2 >> plugin cache file"); >> > + } >> > + }, >> > + >> > + XML { >> > + @Override >> > + public void loadCacheFiles(final PluginCache pluginCache, >> final URL url) throws IOException { >> > + try (final XMLDecoder out = new >> XMLDecoder(url.openStream())) { >> > + @SuppressWarnings("unchecked") >> > + final Map<String, Map<String, PluginEntry>> object >> = (Map<String, Map<String, PluginEntry>>) out.readObject(); >> > + pluginCache.getAllCategories().putAll(object); >> > + } >> > + } >> > >> > - public abstract void writeCache(PluginCache pluginCache, final >> OutputStream os) throws IOException; >> > + @Override >> > + public void writeCache(final PluginCache pluginCache, >> final OutputStream os) { >> > + try (final XMLEncoder out = new XMLEncoder(os)) { >> > + out.writeObject(pluginCache.categories); >> > + } >> > + } >> > + }; >> > >> > /** >> > * Parses a comma-separated list of {@code Format}s. >> > @@ -174,6 +200,15 @@ public class PluginCache { >> > } >> > return prop; >> > } >> > + >> > + public String getExtension() { >> > + return "." + toString().toLowerCase(Locale.ROOT); >> > + } >> > + >> > + public abstract void loadCacheFiles(PluginCache pluginCache, >> URL url) throws IOException; >> > + >> > + public abstract void writeCache(PluginCache pluginCache, >> OutputStream os) throws IOException; >> > + >> > } >> > >> > private final Map<String, Map<String, PluginEntry>> categories = >> new LinkedHashMap<>(); >> > @@ -203,6 +238,44 @@ public class PluginCache { >> > return categories.get(key); >> > } >> > >> > + public void loadCacheFiles(final ClassLoader classLoader) throws >> IOException { >> > + categories.clear(); >> > + for (final Format format : Format.values()) { >> > + final Enumeration<URL> resources = classLoader >> > + .getResources(PluginProcessor.PLUGIN_CACHE_FILE_BASE >> + format.getExtension()); >> > + while (resources.hasMoreElements()) { >> > + final URL url = resources.nextElement(); >> > + format.loadCacheFiles(this, url); >> > + } >> > + } >> > + } >> > + >> > + /** >> > + * 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. >> > + * @deprecated Use {@link #loadCacheFiles(ClassLoader)}. >> > + */ >> > + @Deprecated >> > + public void loadCacheFiles(final Enumeration<URL> resources) >> throws IOException { >> > + categories.clear(); >> > + while (resources.hasMoreElements()) { >> > + Format.DAT.loadCacheFiles(this, resources.nextElement()); >> > + } >> > + } >> > + >> > + /** >> > + * Gets the number of plugin categories registered. >> > + * >> > + * @return number of plugin categories in cache. >> > + */ >> > + public int size() { >> > + return categories.size(); >> > + } >> > + >> > /** >> > * Stores the plugin cache to a given OutputStream. >> > * >> > @@ -237,48 +310,4 @@ public class PluginCache { >> > Format.valueOf(formatStr).writeCache(this, os); >> > } >> > } >> > - >> > - /** >> > - * 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. >> > - */ >> > - public void loadCacheFiles(final Enumeration<URL> resources) >> throws IOException { >> > - categories.clear(); >> > - while (resources.hasMoreElements()) { >> > - final URL url = resources.nextElement(); >> > - try (final DataInputStream in = new DataInputStream(new >> BufferedInputStream(url.openStream()))) { >> > - final int count = in.readInt(); >> > - for (int i = 0; i < count; i++) { >> > - final String category = in.readUTF(); >> > - final Map<String, PluginEntry> m = >> getCategory(category); >> > - final int entries = in.readInt(); >> > - for (int j = 0; j < entries; j++) { >> > - final PluginEntry entry = new PluginEntry(); >> > - entry.setKey(in.readUTF()); >> > - entry.setClassName(in.readUTF()); >> > - entry.setName(in.readUTF()); >> > - entry.setPrintable(in.readBoolean()); >> > - entry.setDefer(in.readBoolean()); >> > - entry.setCategory(category); >> > - if (!m.containsKey(entry.getKey())) { >> > - m.put(entry.getKey(), entry); >> > - } >> > - } >> > - } >> > - } >> > - } >> > - } >> > - >> > - /** >> > - * Gets the number of plugin categories registered. >> > - * >> > - * @return number of plugin categories in cache. >> > - */ >> > - public int size() { >> > - return categories.size(); >> > - } >> > } >> > >> > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5 >> cce8c11/log4j-core/src/main/java/org/apache/logging/log4j/co >> re/config/plugins/util/PluginRegistry.java >> > ---------------------------------------------------------------------- >> > diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/con >> fig/plugins/util/PluginRegistry.java b/log4j-core/src/main/java/org >> /apache/logging/log4j/core/config/plugins/util/PluginRegistry.java >> > index a657f1a..71b841f 100644 >> > --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/con >> fig/plugins/util/PluginRegistry.java >> > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/con >> fig/plugins/util/PluginRegistry.java >> > @@ -164,6 +164,7 @@ public class PluginRegistry { >> > LOGGER.info("Plugin preloads not available from class >> loader {}", loader); >> > } else { >> > cache.loadCacheFiles(resources); >> > + cache.loadCacheFiles(loader); >> > } >> > } catch (final IOException ioe) { >> > LOGGER.warn("Unable to preload plugins", ioe); >> > >> > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5 >> cce8c11/log4j-core/src/main/java/org/apache/logging/log4j/co >> re/util/SortedProperties.java >> > ---------------------------------------------------------------------- >> > diff --git >> > a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/SortedProperties.java >> b/log4j-core/src/main/java/org/apache/logging/log4j/core/uti >> l/SortedProperties.java >> > new file mode 100644 >> > index 0000000..156e41e >> > --- /dev/null >> > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/uti >> l/SortedProperties.java >> > @@ -0,0 +1,47 @@ >> > +/* >> > + * Licensed to the Apache Software Foundation (ASF) under one or more >> > + * contributor license agreements. See the NOTICE file distributed with >> > + * this work for additional information regarding copyright ownership. >> > + * The ASF licenses this file to You 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 org.apache.logging.log4j.core.util; >> > + >> > +import java.util.Collections; >> > +import java.util.Enumeration; >> > +import java.util.Properties; >> > +import java.util.Set; >> > +import java.util.TreeSet; >> > + >> > +/** >> > + * Extends the JRE's {@link Properties} class with sorted keys. >> > + */ >> > +public 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 Enumeration<?> propertyNames() { >> > + // TODO Auto-generated method stub >> > + return super.propertyNames(); >> > + } >> > + >> > + @Override >> > + public Set<String> stringPropertyNames() { >> > + return new TreeSet<>(super.stringPropertyNames()); >> > + } >> > +} >> > \ No newline at end of file >> > >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org >> For additional commands, e-mail: log4j-dev-h...@logging.apache.org >> >> > > > -- > E-Mail: garydgreg...@gmail.com | ggreg...@apache.org > Java Persistence with Hibernate, Second Edition > <https://www.amazon.com/gp/product/1617290459/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1617290459&linkCode=as2&tag=garygregory-20&linkId=cadb800f39946ec62ea2b1af9fe6a2b8> > > <http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1617290459> > JUnit in Action, Second Edition > <https://www.amazon.com/gp/product/1935182021/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182021&linkCode=as2&tag=garygregory-20&linkId=31ecd1f6b6d1eaf8886ac902a24de418%22> > > <http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182021> > Spring Batch in Action > <https://www.amazon.com/gp/product/1935182951/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182951&linkCode=%7B%7BlinkCode%7D%7D&tag=garygregory-20&linkId=%7B%7Blink_id%7D%7D%22%3ESpring+Batch+in+Action> > <http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182951> > Blog: http://garygregory.wordpress.com > Home: http://garygregory.com/ > Tweet! http://twitter.com/GaryGregory > > -- Matt Sicker <boa...@gmail.com>