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.internal; 017 018import javax.money.*; 019import javax.money.spi.RoundingProviderSpi; 020import java.math.MathContext; 021import java.math.RoundingMode; 022import java.time.LocalDate; 023import java.time.LocalDateTime; 024import java.util.*; 025 026/** 027 * Default implementation of a {@link javax.money.spi.RoundingProviderSpi} that creates instances of {@link org 028 * .javamoney.moneta.format.DefaultRounding} that relies on the default fraction units defined by {@link java.util 029 * .Currency#getDefaultFractionDigits()}. 030 */ 031public class DefaultRoundingProvider implements RoundingProviderSpi { 032 033 private static final String DEFAULT_ROUNDING_NAME = "default"; 034 private Set<String> roundingsNames = new HashSet<>(); 035 036 public DefaultRoundingProvider() { 037 roundingsNames.add(DEFAULT_ROUNDING_NAME); 038 roundingsNames = Collections.unmodifiableSet(roundingsNames); 039 } 040 041 @Override 042 public String getProviderName() { 043 return "default"; 044 } 045 046 /** 047 * Evaluate the rounding that match the given query. 048 * 049 * @return the (shared) default rounding instances matching, never null. 050 */ 051 public MonetaryRounding getRounding(RoundingQuery roundingQuery) { 052 if (roundingQuery.get(LocalDateTime.class) != null || roundingQuery.get(LocalDate.class) != null) { 053 return null; 054 } 055 CurrencyUnit currency = roundingQuery.getCurrency(); 056 if (currency != null) { 057 RoundingMode roundingMode = roundingQuery.get(RoundingMode.class); 058 if (roundingMode == null) { 059 roundingMode = RoundingMode.HALF_EVEN; 060 } 061 if (Boolean.TRUE.equals(roundingQuery.getBoolean("cashRounding"))) { 062 if ("CHF".equals(currency.getCurrencyCode())) { 063 return new DefaultCashRounding(currency, RoundingMode.HALF_UP, 5); 064 } else { 065 return new DefaultCashRounding(currency, 1); 066 } 067 } 068 return new DefaultRounding(currency, roundingMode); 069 } 070 Integer scale = roundingQuery.getScale(); 071 if (scale == null) { 072 scale = 2; 073 } 074 MathContext mc = roundingQuery.get(MathContext.class); 075 RoundingMode roundingMode = roundingQuery.get(RoundingMode.class); 076 if (mc != null) { 077 return new DefaultRounding(scale, mc.getRoundingMode()); 078 } else if (roundingMode != null) { 079 return new DefaultRounding(scale, roundingMode); 080 } else if (roundingQuery.getRoundingName() != null && DEFAULT_ROUNDING_NAME.equals(roundingQuery.getRoundingName())) { 081 return Monetary.getDefaultRounding(); 082 } 083 return null; 084 } 085 086 087 @Override 088 public Set<String> getRoundingNames() { 089 return roundingsNames; 090 } 091 092}