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                        int prio = 0;
070                        if (value.contains("{prio=")) {
071                                int index = value.indexOf('}');
072                                if (index > 0) {
073                                        String prioString = value.substring("{prio=".length(),
074                                                        index - 1);
075                                        value = value.substring(index + 1);
076                                        prio = Integer.parseInt(prioString);
077                                        this.priorities.put(key, prio);
078                                }
079                        }
080                        Integer existingPrio = priorities.get(key);
081                        if (Objects.isNull(existingPrio)) {
082                                this.config.put(key, value);
083                        } else if (existingPrio < prio) {
084                                this.config.put(key, value);
085                        } else if (existingPrio == prio) {
086                                throw new IllegalStateException(
087                                                "AmbigousConfiguration 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}