View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements. See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License. You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.logging.log4j.core.config.plugins.processor;
    19
    20  import org.apache.logging.log4j.core.util.Closer;
    21
    22  import java.io.BufferedInputStream;
    23  import java.io.BufferedOutputStream;
    24  import java.io.DataInputStream;
    25  import java.io.DataOutputStream;
    26  import java.io.IOException;
    27  import java.io.OutputStream;
    28  import java.net.URL;
    29  import java.util.Enumeration;
    30  import java.util.LinkedHashMap;
    31  import java.util.Map;
    32
    33  /**
    34   *
    35   */
    36  public class PluginCache {
    37      private final Map<String, Map<String, PluginEntry>> categories =
    38          new LinkedHashMap<String, Map<String, PluginEntry>>();
    39
    40      /**
    41       * Returns all categories of plugins in this cache.
    42       *
    43       * @return all categories of plugins in this cache.
    44       * @since 2.1
    45       */
    46      public Map<String, Map<String, PluginEntry>> getAllCategories() {
    47          return categories;
    48      }
    49
    50      /**
    51       * Gets or creates a category of plugins.
    52       *
    53       * @param category name of category to look up.
    54       * @return plugin mapping of names to plugin entries.
    55       */
    56      public Map<String, PluginEntry> getCategory(final String category) {
    57          final String key = category.toLowerCase();
    58          if (!categories.containsKey(key)) {
    59              categories.put(key, new LinkedHashMap<String, PluginEntry>());
    60          }
    61          return categories.get(key);
    62      }
    63
    64      /**
    65       * Stores the plugin cache to a given OutputStream.
    66       *
    67       * @param os destination to save cache to.
    68       * @throws IOException
    69       */
    70      // NOTE: if this file format is to be changed, the filename should change and this format should still be readable
    71      public void writeCache(final OutputStream os) throws IOException {
    72          final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(os));
    73          try {
    74              // See PluginManager.readFromCacheFiles for the corresponding decoder. Format may not be changed
    75              // without breaking existing Log4j2Plugins.dat files.
    76              out.writeInt(categories.size());
    77              for (final Map.Entry<String, Map<String, PluginEntry>> category : categories.entrySet()) {
    78                  out.writeUTF(category.getKey());
    79                  final Map<String, PluginEntry> m = category.getValue();
    80                  out.writeInt(m.size());
    81                  for (final Map.Entry<String, PluginEntry> entry : m.entrySet()) {
    82                      final PluginEntry plugin = entry.getValue();
    83                      out.writeUTF(plugin.getKey());
    84                      out.writeUTF(plugin.getClassName());
    85                      out.writeUTF(plugin.getName());
    86                      out.writeBoolean(plugin.isPrintable());
    87                      out.writeBoolean(plugin.isDefer());
    88                  }
    89              }
    90          } finally {
    91              Closer.closeSilently(out);
    92          }
    93      }
    94
    95      /**
    96       * Loads and merges all the Log4j plugin cache files specified. Usually, this is obtained via a ClassLoader.
    97       *
    98       * @param resources URLs to all the desired plugin cache files to load.
    99       * @throws IOException
    100      */
    101     public void loadCacheFiles(final Enumeration<URL> resources) throws IOException {
    102         categories.clear();
    103         while (resources.hasMoreElements()) {
    104             final URL url = resources.nextElement();
    105             final DataInputStream in = new DataInputStream(new BufferedInputStream(url.openStream()));
    106             try {
    107                 final int count = in.readInt();
    108                 for (int i = 0; i < count; i++) {
    109                     final String category = in.readUTF();
    110                     final Map<String, PluginEntry> m = getCategory(category);
    111                     final int entries = in.readInt();
    112                     for (int j = 0; j < entries; j++) {
    113                         final PluginEntry entry = new PluginEntry();
    114                         entry.setKey(in.readUTF());
    115                         entry.setClassName(in.readUTF());
    116                         entry.setName(in.readUTF());
    117                         entry.setPrintable(in.readBoolean());
    118                         entry.setDefer(in.readBoolean());
    119                         entry.setCategory(category);
    120                         if (!m.containsKey(entry.getKey())) {
    121                             m.put(entry.getKey(), entry);
    122                         }
    123                     }
    124                 }
    125             } finally {
    126                 Closer.closeSilently(in);
    127             }
    128         }
    129     }
    130
    131     /**
    132      * Gets the number of plugin categories registered.
    133      *
    134      * @return number of plugin categories in cache.
    135      */
    136     public int size() {
    137         return categories.size();
    138     }
    139 }