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