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.Properties; 025import java.util.logging.Level; 026import java.util.logging.Logger; 027 028/** 029 * Loader for the Java Money JSR configuration. 030 * 031 * @author Anatole Tresch 032 */ 033public final class MonetaryConfig { 034 035 private static final Logger LOG = Logger 036 .getLogger(MonetaryConfig.class.getName()); 037 038 private static final MonetaryConfig INSTANCE = new MonetaryConfig(); 039 040 private final Map<String, String> config = new HashMap<>(); 041 private final Map<String, Integer> priorities = new HashMap<>(); 042 043 private MonetaryConfig() { 044 try { 045 Enumeration<URL> urls = getClass().getClassLoader().getResources( 046 "javamoney.properties"); 047 while (urls.hasMoreElements()) { 048 URL url = urls.nextElement(); 049 try { 050 Properties props = new Properties(); 051 props.load(url.openStream()); 052 updateConfig(props); 053 } catch (Exception e) { 054 LOG.log(Level.SEVERE, 055 "Error loading javamoney.properties, ignoring " 056 + url, e); 057 } 058 } 059 } catch (IOException e) { 060 LOG.log(Level.SEVERE, "Error loading javamoney.properties.", e); 061 } 062 } 063 064 private void updateConfig(Properties props) { 065 for (Map.Entry<Object, Object> en : props.entrySet()) { 066 String key = en.getKey().toString(); 067 String value = en.getValue().toString(); 068 int prio = 0; 069 if (key.startsWith("{")) { 070 int index = key.indexOf('}'); 071 if (index > 0) { 072 String prioString = key.substring(1, index); 073 try { 074 prio = Integer.parseInt(prioString); 075 key = key.substring(index + 1); 076 } catch (NumberFormatException e) { 077 LOG.warning("Invalid config key in javamoney.properties: " + key); 078 } 079 } 080 } 081 Integer existingPrio = priorities.get(key); 082 if (existingPrio==null) { 083 priorities.put(key, prio); 084 config.put(key, value); 085 } else if (existingPrio < prio) { 086 priorities.put(key, prio); 087 config.put(key, value); 088 } else if (existingPrio == prio) { 089 String oldValue = props.getProperty(key); 090 if(!value.equals(oldValue)){ 091 throw new IllegalStateException( 092 "AmbiguousConfiguration detected for '" + key + "'."); 093 } 094 } 095 // else ignore entry with lower prio! 096 } 097 } 098 099 public static Map<String, String> getConfig() { 100 return Collections.unmodifiableMap(INSTANCE.config); 101 } 102 103}