001/* 002 * Copyright (c) 2012, 2013, Werner Keil, Credit Suisse (Anatole Tresch). 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. Contributors: Anatole Tresch - initial version. 009 */ 010package org.javamoney.tck.tests.internal; 011 012import javax.money.CurrencyUnit; 013import javax.money.MonetaryAmount; 014import javax.money.MonetaryRounding; 015import javax.money.RoundingContext; 016import javax.money.RoundingContextBuilder; 017import javax.money.RoundingQuery; 018import javax.money.spi.RoundingProviderSpi; 019import java.math.BigDecimal; 020import java.math.RoundingMode; 021import java.util.Calendar; 022import java.util.HashMap; 023import java.util.Map; 024import java.util.Set; 025 026/** 027 * Test ExchangeProvider. Created by Anatole on 26.04.2014. 028 */ 029public class TestRoundingProvider implements RoundingProviderSpi { 030 031 private static final RoundingContext CONTEXT = 032 RoundingContextBuilder.of(TestRoundingProvider.class.getSimpleName(), "NOSCALE").build(); 033 private static final RoundingContext CONTEXT_CASH = 034 RoundingContextBuilder.of(TestRoundingProvider.class.getSimpleName(), "cashRounding").build(); 035 036 private Map<String, MonetaryRounding> customRoundings = new HashMap<>(); 037 038 public TestRoundingProvider() { 039 customRoundings.put("NOSCALE", new MonetaryRounding() { 040 @Override 041 public RoundingContext getRoundingContext() { 042 return CONTEXT; 043 } 044 045 @Override 046 public MonetaryAmount apply(MonetaryAmount value) { 047 return value.getFactory() 048 .setNumber(value.getNumber().numberValue(BigDecimal.class).setScale(0, RoundingMode.HALF_EVEN)) 049 .create(); 050 } 051 }); 052 } 053 054 @Override 055 public MonetaryRounding getRounding(RoundingQuery context) { 056 MonetaryRounding customRounding = customRoundings.get(context.getRoundingName()); 057 if (customRounding != null) { 058 return customRounding; 059 } 060 if (context.getCurrency() == null) { 061 return null; 062 } 063 Boolean cashRounding = context.getBoolean("cashRounding"); 064 if(cashRounding==null) { 065 cashRounding = Boolean.FALSE; 066 } 067 Calendar timestamp = context.get(Calendar.class); 068 if (cashRounding) { 069 if (timestamp != null) { 070 return getCashRounding(context.getCurrency(), timestamp); 071 } 072 return getCashRounding(context.getCurrency()); 073 } else { 074 if ("XAU".equals(context.getCurrency().getCurrencyCode())) { 075 if (timestamp != null) { 076 return new MonetaryRounding() { 077 @Override 078 public RoundingContext getRoundingContext() { 079 return CONTEXT; 080 } 081 082 @Override 083 public MonetaryAmount apply(MonetaryAmount value) { 084 return value.getFactory().setNumber( 085 value.getNumber().numberValue(BigDecimal.class).setScale(2, RoundingMode.UP)) 086 .create(); 087 } 088 }; 089 } 090 return new MonetaryRounding() { 091 @Override 092 public RoundingContext getRoundingContext() { 093 return CONTEXT; 094 } 095 096 @Override 097 public MonetaryAmount apply(MonetaryAmount value) { 098 return value.getFactory() 099 .setNumber(value.getNumber().numberValue(BigDecimal.class).setScale(4, RoundingMode.UP)) 100 .create(); 101 } 102 }; 103 } 104 } 105 return null; 106 } 107 108 109 private MonetaryRounding getCashRounding(CurrencyUnit currency) { 110 if ("XAU".equals(currency.getCurrencyCode())) { 111 return new MonetaryRounding() { 112 @Override 113 public RoundingContext getRoundingContext() { 114 return CONTEXT_CASH; 115 } 116 117 @Override 118 public MonetaryAmount apply(MonetaryAmount value) { 119 return value.getFactory() 120 .setNumber(value.getNumber().numberValue(BigDecimal.class).setScale(1, RoundingMode.DOWN)) 121 .create(); 122 } 123 }; 124 } 125 return null; 126 } 127 128 private MonetaryRounding getCashRounding(CurrencyUnit currency, Calendar timestamp) { 129 if ("XAU".equals(currency.getCurrencyCode()) && timestamp.get(Calendar.YEAR) < 1972) { 130 return new MonetaryRounding() { 131 @Override 132 public RoundingContext getRoundingContext() { 133 return CONTEXT_CASH; 134 } 135 136 @Override 137 public MonetaryAmount apply(MonetaryAmount value) { 138 return value.getFactory() 139 .setNumber(value.getNumber().numberValue(BigDecimal.class).setScale(2, RoundingMode.DOWN)) 140 .create(); 141 } 142 }; 143 } 144 return null; 145 } 146 147 @Override 148 public Set<String> getRoundingNames() { 149 return customRoundings.keySet(); 150 } 151 152 @Override 153 public String getProviderName() { 154 return getClass().getSimpleName(); 155 } 156}