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.activemq.jaas;
018
019import java.io.File;
020import java.util.Map;
021import java.util.concurrent.ConcurrentHashMap;
022
023import org.slf4j.Logger;
024import org.slf4j.LoggerFactory;
025
026public class PropertiesLoader {
027    private static final Logger LOG = LoggerFactory.getLogger(PropertiesLoader.class);
028    private static final Map<FileNameKey, ReloadableProperties> staticCache = new ConcurrentHashMap<FileNameKey, ReloadableProperties>();
029    protected boolean debug;
030
031    public void init(Map options) {
032        debug = booleanOption("debug", options);
033        if (debug) {
034            LOG.debug("Initialized debug");
035        }
036    }
037
038    public ReloadableProperties load(String nameProperty, String fallbackName, Map options) {
039        FileNameKey key = new FileNameKey(nameProperty, fallbackName, options);
040        key.setDebug(debug);
041
042        ReloadableProperties result = staticCache.computeIfAbsent(key, k -> new ReloadableProperties(k));
043        return result.obtained();
044    }
045
046    private static boolean booleanOption(String name, Map options) {
047        return Boolean.parseBoolean((String) options.get(name));
048    }
049
050    public class FileNameKey {
051        final File file;
052        final String absPath;
053        final boolean reload;
054        private boolean decrypt;
055        private boolean debug;
056
057        public FileNameKey(String nameProperty, String fallbackName, Map options) {
058            this.file = new File(baseDir(options), stringOption(nameProperty, fallbackName, options));
059            absPath = file.getAbsolutePath();
060            reload = booleanOption("reload", options);
061            decrypt = booleanOption("decrypt", options);
062        }
063
064        @Override
065        public boolean equals(Object other) {
066            return other instanceof FileNameKey && this.absPath.equals(((FileNameKey) other).absPath);
067        }
068
069        @Override
070        public int hashCode() {
071            return this.absPath.hashCode();
072        }
073
074        public boolean isReload() {
075            return reload;
076        }
077
078        public File file() {
079            return file;
080        }
081
082        public boolean isDecrypt() {
083            return decrypt;
084        }
085
086        public void setDecrypt(boolean decrypt) {
087            this.decrypt = decrypt;
088        }
089
090        private String stringOption(String key, String nameDefault, Map options) {
091            Object result = options.get(key);
092            return result != null ? result.toString() : nameDefault;
093        }
094
095        private File baseDir(Map options) {
096            File baseDir = null;
097            if (options.get("baseDir") != null) {
098                baseDir = new File((String) options.get("baseDir"));
099            } else {
100                if (System.getProperty("java.security.auth.login.config") != null) {
101                    baseDir = new File(System.getProperty("java.security.auth.login.config")).getParentFile();
102                }
103            }
104            if (debug) {
105                LOG.debug("Using basedir=" + baseDir.getAbsolutePath());
106            }
107            return baseDir;
108        }
109
110        @Override
111        public String toString() {
112            return "PropsFile=" + absPath;
113        }
114
115        public void setDebug(boolean debug) {
116            this.debug = debug;
117        }
118
119        public boolean isDebug() {
120            return debug;
121        }
122    }
123
124    /**
125     * For test-usage only.
126     */
127    public static void resetUsersAndGroupsCache() {
128        staticCache.clear();
129    }
130}