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