001/** 002 * Copyright (c) 2012, 2015, 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.convert; 017 018import java.time.LocalDate; 019import java.time.temporal.ChronoUnit; 020import java.util.ArrayList; 021import java.util.Comparator; 022import java.util.List; 023import java.util.Objects; 024import java.util.function.Predicate; 025import java.util.stream.Stream; 026 027import javax.money.CurrencyUnit; 028import javax.money.convert.ConversionQuery; 029import javax.money.convert.ConversionQueryBuilder; 030/** 031 * Class builder to find exchange rate from historical. 032 * @see {@link HistoricConversionQueryBuilder#of(CurrencyUnit)} 033 * @author Otavio Santana 034 * @deprecated 035 */ 036@Deprecated 037public final class HistoricConversionQueryBuilder { 038 039 private final ConversionQueryBuilder conversionQueryBuilder; 040 041 private HistoricConversionQueryBuilder(ConversionQueryBuilder conversionQuery) { 042 this.conversionQueryBuilder = conversionQuery; 043 } 044 045 /** 046 *Create a {@link HistoricConversionQueryBuilder} from currency 047 * @param currencyUnit to be used in term currency. 048 * @return a HistoricConversionQuery from currency 049 * @throws NullPointerException when currency is null 050 */ 051 public static HistoricConversionQueryBuilder of(CurrencyUnit currencyUnit) { 052 Objects.requireNonNull(currencyUnit, "Currency is required"); 053 return new HistoricConversionQueryBuilder(ConversionQueryBuilder.of() 054 .setTermCurrency(currencyUnit)); 055 } 056 057 /** 058 * Set a specify day on {@link HistoricConversionQueryBuilder} 059 * @param localDate 060 * @return this 061 * @throws NullPointerException when {@link LocalDate} is null 062 */ 063 public HistoricConversionQueryWithDayBuilder withDay(LocalDate localDate) { 064 Objects.requireNonNull(localDate); 065 conversionQueryBuilder.set(LocalDate.class, localDate); 066 067 return new HistoricConversionQueryWithDayBuilder(conversionQueryBuilder); 068 } 069 070 /** 071 *Set days on {@link HistoricConversionQueryBuilder} to be used on ExchangeRateProvider, 072 *these parameters will sort to most recent to be more priority than other. 073 * @param localDates 074 * @return this 075 * @throws IllegalArgumentException when is empty or the parameter has an null value 076 */ 077 @SafeVarargs 078 public final HistoricConversionQueryWithDayBuilder withDays(LocalDate... localDates) { 079 Objects.requireNonNull(localDates); 080 if(localDates.length == 0) { 081 throw new IllegalArgumentException("LocalDates are required"); 082 } 083 084 if(Stream.of(localDates).anyMatch(Predicate.isEqual(null))) { 085 throw new IllegalArgumentException("LocalDates cannot be null"); 086 } 087 Comparator<LocalDate> comparator = Comparator.naturalOrder(); 088 LocalDate[] sortedDates = Stream.of(localDates).sorted(comparator.reversed()).toArray(LocalDate[]::new); 089 conversionQueryBuilder.set(LocalDate[].class, sortedDates); 090 091 return new HistoricConversionQueryWithDayBuilder(conversionQueryBuilder); 092 } 093 094 /** 095 *Set days on {@link HistoricConversionQueryBuilder} to be used on ExchangeRateProvider, 096 *these parameters, different of {@link HistoricConversionQueryBuilder#withDays(LocalDate...)}, consider the order already defined. 097 * @param localDates 098 * @return this 099 * @throws IllegalArgumentException when is empty or the parameter has an null value 100 */ 101 @SafeVarargs 102 public final HistoricConversionQueryWithDayBuilder withDaysPriorityDefined(LocalDate... localDates) { 103 Objects.requireNonNull(localDates); 104 if(localDates.length == 0) { 105 throw new IllegalArgumentException("LocalDates are required"); 106 } 107 108 if(Stream.of(localDates).anyMatch(Predicate.isEqual(null))) { 109 throw new IllegalArgumentException("LocalDates cannot be null"); 110 } 111 conversionQueryBuilder.set(LocalDate[].class, localDates); 112 113 return new HistoricConversionQueryWithDayBuilder(conversionQueryBuilder); 114 } 115 116 /** 117 * Set the period of days on {@link HistoricConversionQueryBuilder} 118 * to be used on ExchangeRateProvider, 119 * @param begin 120 * @param end 121 * @return this; 122 * <p>Example:</p> 123 * <pre> 124 * {@code 125 *LocalDate today = LocalDate.parse("2015-04-03"); 126 *LocalDate yesterday = today.minusDays(1); 127 *LocalDate tomorrow = today.plusDays(1); 128 *ConversionQuery query = HistoricConversionQueryBuilder.of(real).onDaysBetween(yesterday, tomorrow).build();//the query with new LocalDate[] {tomorrow, today, yesterday} 129 * } 130 * </pre> 131 * @throws NullPointerException when either begin or end is null 132 * @throws IllegalArgumentException when the begin is bigger than end 133 */ 134 public final HistoricConversionQueryWithDayBuilder withDaysBetween(LocalDate begin, LocalDate end) { 135 Objects.requireNonNull(begin); 136 Objects.requireNonNull(end); 137 if(end.isBefore(begin)) { 138 throw new IllegalArgumentException("The end period should be bigger than the begin period."); 139 } 140 141 int days = (int) ChronoUnit.DAYS.between(begin, end); 142 143 List<LocalDate> dates = new ArrayList<>(); 144 for(int index = days; index >= 0; index--) { 145 dates.add(begin.plusDays(index)); 146 } 147 conversionQueryBuilder.set(LocalDate[].class, dates.toArray(new LocalDate[dates.size()])); 148 149 return new HistoricConversionQueryWithDayBuilder(conversionQueryBuilder); 150 } 151 152 /** 153 * Create the {@link ConversionQuery} just with {@link CurrencyUnit}, to term currency, already defined. 154 * @return the conversion query 155 */ 156 public ConversionQuery build() { 157 return conversionQueryBuilder.build(); 158 } 159 160 @Override 161 public String toString() { 162 StringBuilder sb = new StringBuilder(); 163 sb.append(HistoricConversionQueryBuilder.class.getName()) 164 .append('{').append(" conversionQueryBuilder: ") 165 .append(conversionQueryBuilder).append('}'); 166 return sb.toString(); 167 } 168 169 public class HistoricConversionQueryWithDayBuilder { 170 171 private final ConversionQueryBuilder conversionQueryBuilder; 172 173 HistoricConversionQueryWithDayBuilder( 174 ConversionQueryBuilder conversionQueryBuilder) { 175 this.conversionQueryBuilder = conversionQueryBuilder; 176 } 177 178 /** 179 * Create the {@link ConversionQuery} with {@link LocalDate} and {@link CurrencyUnit} to term currency already defined. 180 * @return the conversion query 181 */ 182 public ConversionQuery build() { 183 return conversionQueryBuilder.build(); 184 } 185 186 @Override 187 public String toString() { 188 StringBuilder sb = new StringBuilder(); 189 sb.append(HistoricConversionQueryWithDayBuilder.class.getName()) 190 .append('{').append(" conversionQueryBuilder: ") 191 .append(conversionQueryBuilder).append('}'); 192 return sb.toString(); 193 } 194 195 } 196 197}