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        private String algorithm;
057
058        public FileNameKey(String nameProperty, String fallbackName, Map options) {
059            this.file = new File(baseDir(options), stringOption(nameProperty, fallbackName, options));
060            absPath = file.getAbsolutePath();
061            reload = booleanOption("reload", options);
062            decrypt = booleanOption("decrypt", options);
063            algorithm = stringOption("algorithm", "PBEWithMD5AndDES", options);
064        }
065
066        @Override
067        public boolean equals(Object other) {
068            return other instanceof FileNameKey && this.absPath.equals(((FileNameKey) other).absPath);
069        }
070
071        @Override
072        public int hashCode() {
073            return this.absPath.hashCode();
074        }
075
076        public boolean isReload() {
077            return reload;
078        }
079
080        public File file() {
081            return file;
082        }
083
084        public boolean isDecrypt() {
085            return decrypt;
086        }
087
088        public void setDecrypt(boolean decrypt) {
089            this.decrypt = decrypt;
090        }
091
092        public String getAlgorithm() {
093            return algorithm;
094        }
095
096        private String stringOption(String key, String nameDefault, Map options) {
097            Object result = options.get(key);
098            return result != null ? result.toString() : nameDefault;
099        }
100
101        private File baseDir(Map options) {
102            File baseDir = null;
103            if (options.get("baseDir") != null) {
104                baseDir = new File((String) options.get("baseDir"));
105            } else {
106                if (System.getProperty("java.security.auth.login.config") != null) {
107                    baseDir = new File(System.getProperty("java.security.auth.login.config")).getParentFile();
108                }
109            }
110            if (debug) {
111                LOG.debug("Using basedir=" + baseDir.getAbsolutePath());
112            }
113            return baseDir;
114        }
115
116        @Override
117        public String toString() {
118            return "PropsFile=" + absPath;
119        }
120
121        public void setDebug(boolean debug) {
122            this.debug = debug;
123        }
124
125        public boolean isDebug() {
126            return debug;
127        }
128    }
129
130    /**
131     * For test-usage only.
132     */
133    public static void resetUsersAndGroupsCache() {
134        staticCache.clear();
135    }
136}