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