001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.util; 018 019import java.io.IOException; 020import java.io.InputStream; 021import java.net.URL; 022import java.util.Properties; 023 024import org.apache.logging.log4j.Logger; 025import org.apache.logging.log4j.status.StatusLogger; 026 027/** 028 * <em>Consider this class private.</em> 029 * <p> 030 * Helps access properties. This utility provides a method to override system properties by specifying properties 031 * in a properties file. 032 * </p> 033 */ 034public final class PropertiesUtil { 035 036 private static final PropertiesUtil LOG4J_PROPERTIES = new PropertiesUtil("log4j2.component.properties"); 037 038 private static final Logger LOGGER = StatusLogger.getLogger(); 039 040 private final Properties props; 041 042 /** 043 * Constructs a PropertiesUtil using a given Properties object as its source of defined properties. 044 * 045 * @param props the Properties to use by default 046 */ 047 public PropertiesUtil(final Properties props) { 048 this.props = props; 049 } 050 051 /** 052 * Loads and closes the given property input stream. 053 * If an error occurs, log to the status logger. 054 * 055 * @param in 056 * a property input stream. 057 * @param source 058 * a source object describing the source, like a resource string 059 * or a URL. 060 * @return a new Properties object 061 */ 062 static Properties loadClose(final InputStream in, final Object source) { 063 final Properties props = new Properties(); 064 if (null != in) { 065 try { 066 props.load(in); 067 } catch (final IOException e) { 068 LOGGER.error("Unable to read {}", source, e); 069 } finally { 070 try { 071 in.close(); 072 } catch (final IOException e) { 073 LOGGER.error("Unable to close {}", source, e); 074 } 075 } 076 } 077 return props; 078 } 079 080 /** 081 * Constructs a PropertiesUtil for a given properties file name on the classpath. The properties specified in this 082 * file are used by default. If a property is not defined in this file, then the equivalent system property is 083 * used. 084 * 085 * @param propertiesFileName the location of properties file to load 086 */ 087 public PropertiesUtil(final String propertiesFileName) { 088 @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") 089 final Properties properties = new Properties(); 090 for (final URL url : LoaderUtil.findResources(propertiesFileName)) { 091 InputStream in = null; 092 try { 093 in = url.openStream(); 094 properties.load(in); 095 } catch (final IOException ioe) { 096 LOGGER.error("Unable to read {}", url.toString(), ioe); 097 } finally { 098 if (in != null) { 099 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}