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 java.io.BufferedInputStream;
21  import java.io.BufferedOutputStream;
22  import java.io.DataInputStream;
23  import java.io.DataOutputStream;
24  import java.io.IOException;
25  import java.io.OutputStream;
26  import java.net.URL;
27  import java.util.Enumeration;
28  import java.util.Map;
29  import java.util.concurrent.ConcurrentMap;
30  
31  import org.apache.logging.log4j.core.config.plugins.util.PluginRegistry;
32  
33  /**
34   *
35   */
36  public class PluginCache {
37      private final transient PluginRegistry<PluginEntry> pluginCategories = new PluginRegistry<PluginEntry>();
38  
39      /**
40       * Gets or creates a category of plugins.
41       *
42       * @param category name of category to look up.
43       * @return plugin mapping of names to plugin entries.
44       */
45      public ConcurrentMap<String, PluginEntry> getCategory(final String category) {
46          return pluginCategories.getCategory(category);
47      }
48  
49      /**
50       * Stores the plugin cache to a given OutputStream.
51       *
52       * @param os destination to save cache to.
53       * @throws IOException
54       */
55      public void writeCache(final OutputStream os) throws IOException {
56          final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(os));
57          try {
58              out.writeInt(pluginCategories.getCategoryCount());
59              for (final Map.Entry<String, ConcurrentMap<String, PluginEntry>> category : pluginCategories.getCategories()) {
60                  out.writeUTF(category.getKey());
61                  final Map<String, PluginEntry> m = category.getValue();
62                  out.writeInt(m.size());
63                  for (final Map.Entry<String, PluginEntry> entry : m.entrySet()) {
64                      final PluginEntry plugin = entry.getValue();
65                      out.writeUTF(plugin.getKey());
66                      out.writeUTF(plugin.getClassName());
67                      out.writeUTF(plugin.getName());
68                      out.writeBoolean(plugin.isPrintable());
69                      out.writeBoolean(plugin.isDefer());
70                  }
71              }
72          } finally {
73              out.close();
74          }
75      }
76  
77      /**
78       * Loads and merges all the Log4j plugin cache files specified. Usually, this is obtained via a ClassLoader.
79       *
80       * @param resources URLs to all the desired plugin cache files to load.
81       * @throws IOException
82       */
83      public void loadCacheFiles(final Enumeration<URL> resources) throws IOException {
84          pluginCategories.clear();
85          while (resources.hasMoreElements()) {
86              final URL url = resources.nextElement();
87              final DataInputStream in = new DataInputStream(new BufferedInputStream(url.openStream()));
88              try {
89                  final int count = in.readInt();
90                  for (int i = 0; i < count; i++) {
91                      final String category = in.readUTF();
92                      final ConcurrentMap<String, PluginEntry> m = pluginCategories.getCategory(category);
93                      final int entries = in.readInt();
94                      for (int j = 0; j < entries; j++) {
95                          final PluginEntry entry = new PluginEntry();
96                          entry.setKey(in.readUTF());
97                          entry.setClassName(in.readUTF());
98                          entry.setName(in.readUTF());
99                          entry.setPrintable(in.readBoolean());
100                         entry.setDefer(in.readBoolean());
101                         entry.setCategory(category);
102                         m.putIfAbsent(entry.getKey(), entry);
103                     }
104                 }
105             } finally {
106                 in.close();
107             }
108         }
109     }
110 
111     /**
112      * Gets the number of plugin categories registered.
113      *
114      * @return number of plugin categories in cache.
115      */
116     public int size() {
117         return pluginCategories.getCategoryCount();
118     }
119 }