001/*
002 * ObjectLab, http://www.objectlab.co.uk/open is sponsoring the ObjectLab Kit.
003 *
004 * Based in London, we are world leaders in the design and development
005 * of bespoke applications for the securities financing markets.
006 *
007 * <a href="http://www.objectlab.co.uk/open">Click here to learn more</a>
008 *           ___  _     _           _   _          _
009 *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
010 *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
011 *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
012 *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
013 *                   |__/
014 *
015 *                     www.ObjectLab.co.uk
016 *
017 * $Id$
018 *
019 * Copyright 2006 the original author or authors.
020 *
021 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
022 * use this file except in compliance with the License. You may obtain a copy of
023 * the License at
024 *
025 * http://www.apache.org/licenses/LICENSE-2.0
026 *
027 * Unless required by applicable law or agreed to in writing, software
028 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
029 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
030 * License for the specific language governing permissions and limitations under
031 * the License.
032 */
033package net.objectlab.kit.datecalc.common;
034
035import java.io.Serializable;
036import java.util.Collections;
037import java.util.HashSet;
038import java.util.Set;
039import java.util.concurrent.ConcurrentHashMap;
040import java.util.concurrent.ConcurrentMap;
041
042import net.objectlab.kit.datecalc.common.ccy.CurrencyCalculatorConfig;
043import net.objectlab.kit.datecalc.common.ccy.DefaultCurrencyCalculatorConfig;
044
045/**
046 * Base class for all calculator factories, it handles the holiday registration.
047 *
048 * @author Marcin Jekot
049 *
050 * @param <E>
051 *            a representation of a date, typically JDK: Date, Calendar;
052 *            Joda:LocalDate, YearMonthDay
053 *
054 */
055public abstract class AbstractKitCalculatorsFactory<E extends Serializable> implements KitCalculatorsFactory<E> {
056
057    private final ConcurrentMap<String, HolidayCalendar<E>> holidays = new ConcurrentHashMap<>();
058
059    private CurrencyCalculatorConfig currencyCalculatorConfig = new DefaultCurrencyCalculatorConfig();
060
061    /**
062     * Use this method register a specific currency config, if not provided then the DefaultCurrencyCalculatorConfig will be given.
063     * @param config that specifies the set of currencies subject to USD T+1 and the WorkingWeeks per currency.
064     */
065    @Override
066    public void setCurrencyCalculatorConfig(final CurrencyCalculatorConfig config) {
067        currencyCalculatorConfig = config;
068    }
069
070    /**
071     * Provides the registered instance of currencyCalculatorConfig or use DefaultCurrencyCalculatorConfig if none registered.
072     * @see DefaultCurrencyCalculatorConfig
073     */
074    @Override
075    public CurrencyCalculatorConfig getCurrencyCalculatorConfig() {
076        if (currencyCalculatorConfig == null) {
077            currencyCalculatorConfig = new DefaultCurrencyCalculatorConfig();
078        }
079        return currencyCalculatorConfig;
080    }
081
082    /**
083     * Use this method to register a given calendar, it will replace any
084     * existing one with the same name. An immutable copy is made so that any changes outside this class
085     * will have no affect. It won't update any existing DateCalculator as these should
086     * not be amended whilst in existence (we could otherwise get inconsistent
087     * results).
088     *
089     * @param name
090     *            the calendar name to register these holidays under.
091     * @param holidaysCalendar
092     *            a calendar containing a set of holidays (non-working days).
093     */
094    @Override
095    public KitCalculatorsFactory<E> registerHolidays(final String name, final HolidayCalendar<E> holidaysCalendar) {
096        if (name != null) {
097            final Set<E> hol = new HashSet<>();
098            if (holidaysCalendar != null && holidaysCalendar.getHolidays() != null) {
099                hol.addAll(holidaysCalendar.getHolidays());
100            }
101            final DefaultHolidayCalendar<E> defaultHolidayCalendar = new DefaultHolidayCalendar<>(hol);
102            if (holidaysCalendar != null) {
103                defaultHolidayCalendar.setEarlyBoundary(holidaysCalendar.getEarlyBoundary());
104                defaultHolidayCalendar.setLateBoundary(holidaysCalendar.getLateBoundary());
105            }
106            this.holidays.put(name, new ImmutableHolidayCalendar<E>(holidaysCalendar));
107        }
108        return this;
109    }
110
111    /**
112     * Check if a calendar of a given name is already registered.
113     * @return true if the holiday name is registered.
114     */
115    @Override
116    public boolean isHolidayCalendarRegistered(final String name) {
117        return name != null && this.holidays.containsKey(name);
118    }
119
120    /**
121     * Provides an immutable Holiday Calendar with that name if registered, null if not registered
122     * @return an immutable Holiday Calendar that is registered, null if not registered.
123     */
124    @Override
125    public HolidayCalendar<E> getHolidayCalendar(final String name) {
126        return holidays.get(name);
127    }
128
129    /**
130     * Used by extensions to set holidays in a DateCalculator.
131     *
132     * @param name
133     *            holiday name
134     * @param dc
135     *            the date calculator to configure.
136     */
137    protected void setHolidays(final String name, final DateCalculator<E> dc) {
138        if (name != null) {
139            dc.setHolidayCalendar(holidays.get(name));
140        }
141    }
142
143    /**
144     * Provides the immutable set of registered calendar names
145     */
146    @Override
147    public Set<String> getRegisteredHolidayCalendarNames() {
148        return Collections.unmodifiableSet(holidays.keySet());
149    }
150
151    /**
152     * Unregister a given holiday calendar
153     * @param calendarName
154     *          the calendar name to unregister.
155     */
156    @Override
157    public KitCalculatorsFactory<E> unregisterHolidayCalendar(final String calendarName) {
158        holidays.remove(calendarName);
159        return this;
160    }
161
162    /**
163     * unregister all holiday calendars;
164     */
165    @Override
166    public KitCalculatorsFactory<E> unregisterAllHolidayCalendars() {
167        holidays.clear();
168        return this;
169    }
170
171    /**
172     * Method that may be called by the specialised factory methods and will fetch the registered holidayCalendar for all 3 currencies 
173     * and the working weeks via the currencyCalculatorConfig and assigning currencyCalculatorConfig to the builder, 
174     * using the DefaultCurrencyCalculatorConfig if not modified.
175     * @param builder the original builder
176     * @return same instance of builder but modified
177     */
178    protected CurrencyDateCalculatorBuilder<E> configureCurrencyCalculatorBuilder(final CurrencyDateCalculatorBuilder<E> builder) {
179        return builder//
180                .ccy1Calendar(getHolidayCalendar(builder.getCcy1())) //
181                .ccy1Week(getCurrencyCalculatorConfig().getWorkingWeek(builder.getCcy1())) //
182                .ccy2Calendar(getHolidayCalendar(builder.getCcy2())) //
183                .ccy2Week(getCurrencyCalculatorConfig().getWorkingWeek(builder.getCcy2())) //
184                .crossCcyCalendar(getHolidayCalendar(builder.getCrossCcy())) //
185                .crossCcyWeek(getCurrencyCalculatorConfig().getWorkingWeek(builder.getCrossCcy())) //
186                .currencyCalculatorConfig(getCurrencyCalculatorConfig());
187    }
188}
189
190/*
191 * ObjectLab, http://www.objectlab.co.uk/open is sponsoring the ObjectLab Kit.
192 *
193 * Based in London, we are world leaders in the design and development
194 * of bespoke applications for the securities financing markets.
195 *
196 * <a href="http://www.objectlab.co.uk/open">Click here to learn more about us</a>
197 *           ___  _     _           _   _          _
198 *          / _ \| |__ (_) ___  ___| |_| |    __ _| |__
199 *         | | | | '_ \| |/ _ \/ __| __| |   / _` | '_ \
200 *         | |_| | |_) | |  __/ (__| |_| |__| (_| | |_) |
201 *          \___/|_.__// |\___|\___|\__|_____\__,_|_.__/
202 *                   |__/
203 *
204 *                     www.ObjectLab.co.uk
205 */