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  package org.apache.logging.log4j.util;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.net.URL;
22  import java.util.Enumeration;
23  import java.util.Properties;
24  
25  import org.apache.logging.log4j.Logger;
26  import org.apache.logging.log4j.status.StatusLogger;
27  
28  /**
29   * <em>Consider this class private.</em>
30   * <p>
31   * Helps access properties. This utility provides a method to override system properties by specifying properties
32   * in a properties file.
33   * </p>
34   */
35  public final class PropertiesUtil {
36  
37      private static final PropertiesUtil LOG4J_PROPERTIES = new PropertiesUtil("log4j2.component.properties");
38  
39      private static final Logger LOGGER = StatusLogger.getLogger();
40  
41      private final Properties props;
42  
43      /**
44       * Constructs a PropertiesUtil using a given Properties object as its source of defined properties.
45       *
46       * @param props the Properties to use by default
47       */
48      public PropertiesUtil(final Properties props) {
49          this.props = props;
50      }
51  
52      /**
53       * Loads and closes the given property input stream.
54       * If an error occurs, log to the status logger.
55       *
56       * @param in
57       *            a property input stream.
58       * @param source
59       *            a source object describing the source, like a resource string
60       *            or a URL.
61       * @return a new Properties object
62       */
63      static Properties loadClose(final InputStream in, final Object source) {
64          final Properties props = new Properties();
65          if (null != in) {
66              try {
67                  props.load(in);
68              } catch (final IOException e) {
69                  LOGGER.error("Unable to read {}", source, e);
70              } finally {
71                  try {
72                      in.close();
73                  } catch (final IOException e) {
74                      LOGGER.error("Unable to close {}", source, e);
75                  }
76              }
77          }
78          return props;
79      }
80  
81      /**
82       * Constructs a PropertiesUtil for a given properties file name on the classpath. The properties specified in this
83       * file are used by default. If a property is not defined in this file, then the equivalent system property is
84       * used.
85       *
86       * @param propsLocn the location of properties file to load
87       */
88      public PropertiesUtil(final String propsLocn) {
89          final ClassLoader loader = LoaderUtil.getThreadContextClassLoader();
90          @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
91          final
92          Properties properties = new Properties();
93              try {
94                  final Enumeration<URL> enumeration = loader.getResources(propsLocn);
95                  while (enumeration.hasMoreElements()) {
96                      final URL url = enumeration.nextElement();
97                      final InputStream in = url.openStream();
98                      try {
99                          properties.load(in);
100                     } catch (final IOException ioe) {
101                         LOGGER.error("Unable to read {}", url.toString());
102                     } finally {
103                         try {
104                             in.close();
105                         } catch (final IOException ioe) {
106                             LOGGER.error("Unable to close {}", url.toString(), ioe);
107                         }
108                     }
109 
110                 }
111 
112             } catch (final IOException ioe) {
113                 LOGGER.error("Unable to access {}", propsLocn, ioe);
114             }
115         this.props = properties;
116     }
117 
118     /**
119      * Returns the PropertiesUtil used by Log4j.
120      *
121      * @return the main Log4j PropertiesUtil instance.
122      */
123     public static PropertiesUtil getProperties() {
124         return LOG4J_PROPERTIES;
125     }
126 
127     /**
128      * Gets the named property as a String.
129      *
130      * @param name the name of the property to look up
131      * @return the String value of the property or {@code null} if undefined.
132      */
133     public String getStringProperty(final String name) {
134         String prop = null;
135         try {
136             prop = System.getProperty(name);
137         } catch (final SecurityException ignored) {
138             // Ignore
139         }
140         return prop == null ? props.getProperty(name) : prop;
141     }
142 
143     /**
144      * Gets the named property as an integer.
145      *
146      * @param name         the name of the property to look up
147      * @param defaultValue the default value to use if the property is undefined
148      * @return the parsed integer value of the property or {@code defaultValue} if it was undefined or could not be
149      * parsed.
150      */
151     public int getIntegerProperty(final String name, final int defaultValue) {
152         String prop = null;
153         try {
154             prop = System.getProperty(name);
155         } catch (final SecurityException ignored) {
156             // Ignore
157         }
158         if (prop == null) {
159             prop = props.getProperty(name);
160         }
161         if (prop != null) {
162             try {
163                 return Integer.parseInt(prop);
164             } catch (final Exception ex) {
165                 return defaultValue;
166             }
167         }
168         return defaultValue;
169     }
170 
171     /**
172      * Gets the named property as a long.
173      *
174      * @param name         the name of the property to look up
175      * @param defaultValue the default value to use if the property is undefined
176      * @return the parsed long value of the property or {@code defaultValue} if it was undefined or could not be
177      * parsed.
178      */
179     public long getLongProperty(final String name, final long defaultValue) {
180         String prop = null;
181         try {
182             prop = System.getProperty(name);
183         } catch (final SecurityException ignored) {
184             // Ignore
185         }
186         if (prop == null) {
187             prop = props.getProperty(name);
188         }
189         if (prop != null) {
190             try {
191                 return Long.parseLong(prop);
192             } catch (final Exception ex) {
193                 return defaultValue;
194             }
195         }
196         return defaultValue;
197     }
198 
199     /**
200      * Gets the named property as a String.
201      *
202      * @param name         the name of the property to look up
203      * @param defaultValue the default value to use if the property is undefined
204      * @return the String value of the property or {@code defaultValue} if undefined.
205      */
206     public String getStringProperty(final String name, final String defaultValue) {
207         final String prop = getStringProperty(name);
208         return (prop == null) ? defaultValue : prop;
209     }
210 
211     /**
212      * Gets the named property as a boolean value. If the property matches the string {@code "true"} (case-insensitive),
213      * then it is returned as the boolean value {@code true}. Any other non-{@code null} text in the property is
214      * considered {@code false}.
215      *
216      * @param name the name of the property to look up
217      * @return the boolean value of the property or {@code false} if undefined.
218      */
219     public boolean getBooleanProperty(final String name) {
220         return getBooleanProperty(name, false);
221     }
222 
223     /**
224      * Gets the named property as a boolean value.
225      *
226      * @param name         the name of the property to look up
227      * @param defaultValue the default value to use if the property is undefined
228      * @return the boolean value of the property or {@code defaultValue} if undefined.
229      */
230     public boolean getBooleanProperty(final String name, final boolean defaultValue) {
231         final String prop = getStringProperty(name);
232         return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop);
233     }
234 
235     /**
236      * Return the system properties or an empty Properties object if an error occurs.
237      * @return The system properties.
238      */
239     public static Properties getSystemProperties() {
240         try {
241             return new Properties(System.getProperties());
242         } catch (final SecurityException ex) {
243             LOGGER.error("Unable to access system properties.", ex);
244             // Sandboxed - can't read System Properties
245             return new Properties();
246         }
247     }
248 }