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     */
017    package org.apache.logging.log4j.util;
018    
019    import java.io.IOException;
020    import java.io.InputStream;
021    import java.net.URL;
022    import java.util.Enumeration;
023    import java.util.Properties;
024    
025    import org.apache.logging.log4j.Logger;
026    import org.apache.logging.log4j.status.StatusLogger;
027    
028    /**
029     * <em>Consider this class private.</em>
030     * <p>
031     * Helps access properties.
032     * </p>
033     */
034    public 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        public PropertiesUtil(final Properties props) {
043            this.props = props;
044        }
045    
046        /**
047         * Loads and closes the given property input stream.
048         * If an error occurs, log to the status logger.
049         *
050         * @param in
051         *            a property input stream.
052         * @param source
053         *            a source object describing the source, like a resource string
054         *            or a URL.
055         * @return a new Properties object
056         */
057        static Properties loadClose(final InputStream in, final Object source) {
058            final Properties props = new Properties();
059            if (null != in) {
060                try {
061                    props.load(in);
062                } catch (final IOException e) {
063                    LOGGER.error("Unable to read {}", source, e);
064                } finally {
065                    try {
066                        in.close();
067                    } catch (final IOException e) {
068                        LOGGER.error("Unable to close {}", source, e);
069                    }
070                }
071            }
072            return props;
073        }
074    
075        public PropertiesUtil(final String propsLocn) {
076            final ClassLoader loader = ProviderUtil.findClassLoader();
077            @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
078            final
079            Properties properties = new Properties();
080                try {
081                    final Enumeration<URL> enumeration = loader.getResources(propsLocn);
082                    while (enumeration.hasMoreElements()) {
083                        final URL url = enumeration.nextElement();
084                        final InputStream in = url.openStream();
085                        try {
086                            properties.load(in);
087                        } catch (final IOException ioe) {
088                            LOGGER.error("Unable to read {}", url.toString());
089                        } finally {
090                            try {
091                                in.close();
092                            } catch (final IOException ioe) {
093                                LOGGER.error("Unable to close {}", url.toString(), ioe);
094                            }
095                        }
096    
097                    }
098    
099                } catch (final IOException ioe) {
100                    LOGGER.error("Unable to access {}", propsLocn, ioe);
101                }
102            this.props = properties;
103        }
104    
105        public static PropertiesUtil getProperties() {
106            return LOG4J_PROPERTIES;
107        }
108    
109        public String getStringProperty(final String name) {
110            String prop = null;
111            try {
112                prop = System.getProperty(name);
113            } catch (final SecurityException ignored) {
114                // Ignore
115            }
116            return prop == null ? props.getProperty(name) : prop;
117        }
118    
119    
120        public int getIntegerProperty(final String name, final int defaultValue) {
121            String prop = null;
122            try {
123                prop = System.getProperty(name);
124            } catch (final SecurityException ignored) {
125                // Ignore
126            }
127            if (prop == null) {
128                prop = props.getProperty(name);
129            }
130            if (prop != null) {
131                try {
132                    return Integer.parseInt(prop);
133                } catch (final Exception ex) {
134                    return defaultValue;
135                }
136            }
137            return defaultValue;
138        }
139    
140    
141        public long getLongProperty(final String name, final long defaultValue) {
142            String prop = null;
143            try {
144                prop = System.getProperty(name);
145            } catch (final SecurityException ignored) {
146                // Ignore
147            }
148            if (prop == null) {
149                prop = props.getProperty(name);
150            }
151            if (prop != null) {
152                try {
153                    return Long.parseLong(prop);
154                } catch (final Exception ex) {
155                    return defaultValue;
156                }
157            }
158            return defaultValue;
159        }
160    
161        public String getStringProperty(final String name, final String defaultValue) {
162            final String prop = getStringProperty(name);
163            return (prop == null) ? defaultValue : prop;
164        }
165    
166        public boolean getBooleanProperty(final String name) {
167            return getBooleanProperty(name, false);
168        }
169    
170        public boolean getBooleanProperty(final String name, final boolean defaultValue) {
171            final String prop = getStringProperty(name);
172            return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop);
173        }
174    
175        /**
176         * Return the system properties or an empty Properties object if an error occurs.
177         * @return The system properties.
178         */
179        public static Properties getSystemProperties() {
180            try {
181                return new Properties(System.getProperties());
182            } catch (final SecurityException ex) {
183                LOGGER.error("Unable to access system properties.", ex);
184                // Sandboxed - can't read System Properties
185                return new Properties();
186            }
187        }
188    }