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