001/*
002 * CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE CONDITION THAT YOU
003 * ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT. PLEASE READ THE TERMS AND CONDITIONS OF THIS
004 * AGREEMENT CAREFULLY. BY DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF
005 * THE AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE" BUTTON AT THE
006 * BOTTOM OF THIS PAGE. Specification: JSR-354 Money and Currency API ("Specification") Copyright
007 * (c) 2012-2013, Credit Suisse All rights reserved.
008 */
009package org.javamoney.moneta.spi.base;
010
011import javax.money.MonetaryAmount;
012import javax.money.MonetaryAmountFactory;
013import javax.money.MonetaryAmountFactoryQuery;
014import javax.money.spi.MonetaryAmountsSingletonQuerySpi;
015import java.util.Collection;
016import java.util.HashSet;
017import java.util.Set;
018
019/**
020 * SPI (core) for the backing implementation of the {@link javax.money.Monetary} singleton, implementing
021 * the query functionality for amounts.
022 *
023 * @author Anatole Tresch
024 */
025public abstract class BaseMonetaryAmountsSingletonQuerySpi implements MonetaryAmountsSingletonQuerySpi{
026
027    /**
028     * Checks if an {@link javax.money.MonetaryAmountFactory} is matching the given query.
029     *
030     * @param query the factory query, not null.
031     * @return true, if at least one {@link javax.money.MonetaryAmountFactory} matches the query.
032     */
033    public boolean isAvailable(MonetaryAmountFactoryQuery query) {
034        return !getAmountFactories(query).isEmpty();
035    }
036
037    /**
038     * Executes the query and returns the {@link javax.money.MonetaryAmount} implementation type found,
039     * if there is only one type.
040     * If multiple types match the query, the first one is selected.
041     *
042     * @param query the factory query, not null.
043     * @return the type found, or null.
044     */
045    public Class<? extends MonetaryAmount> getAmountType(MonetaryAmountFactoryQuery query) {
046        MonetaryAmountFactory<?> f = getAmountFactory(query);
047        if (f != null) {
048            return f.getAmountType();
049        }
050        return null;
051    }
052
053    /**
054     * Executes the query and returns the {@link javax.money.MonetaryAmount} implementation types found.
055     *
056     * @param query the factory query, not null.
057     * @return the type found, or null.
058     */
059    public Collection<Class<? extends MonetaryAmount>> getAmountTypes(MonetaryAmountFactoryQuery query) {
060        Collection<MonetaryAmountFactory<? extends MonetaryAmount>> factories = getAmountFactories(query);
061        Set<Class<? extends MonetaryAmount>> result = new HashSet<>();
062        for(MonetaryAmountFactory f:factories){
063            //noinspection unchecked
064            result.add(f.getAmountType());
065        }
066        return result;
067    }
068
069    /**
070     * Executes the query and returns the {@link javax.money.MonetaryAmountFactory} implementation type found,
071     * if there is only one type. If multiple types match the query, the first one is selected.
072     *
073     * @param query the factory query, not null.
074     * @return the type found, or null.
075     */
076    public MonetaryAmountFactory getAmountFactory(MonetaryAmountFactoryQuery query) {
077        Collection<MonetaryAmountFactory<?>> factories = getAmountFactories(query);
078        if (factories.isEmpty()) {
079            return null;
080        }
081        return factories.iterator().next();
082    }
083
084}