001/**
002 * Copyright (c) 2012, 2014, Credit Suisse (Anatole Tresch), Werner Keil and others by the @author tag.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy of
006 * the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 */
016package org.javamoney.moneta.spi;
017
018import java.io.IOException;
019import java.net.URL;
020import java.util.Collections;
021import java.util.Enumeration;
022import java.util.HashMap;
023import java.util.Map;
024import java.util.Objects;
025import java.util.Properties;
026import java.util.logging.Level;
027import java.util.logging.Logger;
028
029/**
030 * Loader for the Java Money JSR configuration.
031 *
032 * @author Anatole Tresch
033 */
034public final class MonetaryConfig {
035
036    private static final Logger LOG = Logger
037            .getLogger(MonetaryConfig.class.getName());
038
039    private static final MonetaryConfig INSTANCE = new MonetaryConfig();
040
041    private Map<String, String> config = new HashMap<>();
042    private Map<String, Integer> priorities = new HashMap<>();
043
044    private MonetaryConfig() {
045        try {
046            Enumeration<URL> urls = getClass().getClassLoader().getResources(
047                    "javamoney.properties");
048            while (urls.hasMoreElements()) {
049                URL url = urls.nextElement();
050                try {
051                    Properties props = new Properties();
052                    props.load(url.openStream());
053                    updateConfig(props);
054                } catch (Exception e) {
055                    LOG.log(Level.SEVERE,
056                            "Error loading javamoney.properties, ignoring "
057                                    + url, e);
058                }
059            }
060        } catch (IOException e) {
061            LOG.log(Level.SEVERE, "Error loading javamoney.properties.", e);
062        }
063    }
064
065    private void updateConfig(Properties props) {
066        for (Map.Entry<Object, Object> en : props.entrySet()) {
067            String key = en.getKey().toString();
068            String value = en.getValue().toString();
069            Integer existingPrio = priorities.get(key);
070            int prio = 0;
071            if (value.startsWith("{prio=")) {
072                int index = value.indexOf('}');
073                if (index > 0) {
074                    String prioString = value.substring("{prio=".length(),
075                            index);
076                    value = value.substring(index + 1);
077                    prio = Integer.parseInt(prioString);
078                    priorities.put(key, prio);
079                }
080            }
081            if (Objects.isNull(existingPrio)) {
082                config.put(key, value);
083            } else if (existingPrio < prio) {
084                config.put(key, value);
085            } else if (existingPrio == prio) {
086                throw new IllegalStateException(
087                        "AmbiguousConfiguration detected for '" + key + "'.");
088            }
089            // else ignore entry with lower prio!
090        }
091    }
092
093    public static Map<String, String> getConfig() {
094        return Collections.unmodifiableMap(INSTANCE.config);
095    }
096
097}