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 (key.startsWith("{")) { 071 int index = key.indexOf('}'); 072 if (index > 0) { 073 String prioString = key.substring(1, index); 074 try { 075 prio = Integer.parseInt(prioString); 076 key = key.substring(index + 1); 077 } catch (NumberFormatException e) { 078 LOG.warning("Invalid config key in javamoney.properties: " + key); 079 } 080 } 081 } 082 Integer existingPrio = priorities.get(key); 083 if (Objects.isNull(existingPrio)) { 084 priorities.put(key, prio); 085 config.put(key, value); 086 } else if (existingPrio < prio) { 087 priorities.put(key, prio); 088 config.put(key, value); 089 } else if (existingPrio == prio) { 090 throw new IllegalStateException( 091 "AmbiguousConfiguration detected for '" + key + "'."); 092 } 093 // else ignore entry with lower prio! 094 } 095 } 096 097 public static Map<String, String> getConfig() { 098 return Collections.unmodifiableMap(INSTANCE.config); 099 } 100 101}