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