Package com.opengamma.financial.convention.calendar

Source Code of com.opengamma.financial.convention.calendar.CalendarFactory

/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.convention.calendar;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import org.joda.convert.FromString;

import com.opengamma.OpenGammaRuntimeException;

/**
* Factory to obtain instances of {@code Calendar}.
* <p>
* The holidays and country details are read from a properties file.
*/
public final class CalendarFactory {
  // REVIEW: This is really quite a bad implementation. Bank Holiday dates need to be pulled
  // from a database or a more easily updated source. It should probably be possible
  // to update the data with the system running instead of at initialization.
  // emcleod 20-8-2013 This factory is only used in testing, so can probably be safely
  // deleted

  /**
   * Singleton instance.
   */
  public static final CalendarFactory INSTANCE = new CalendarFactory();

  /**
   * Map of convention name to convention.
   */
  private final Map<String, Calendar> _calendarMap = new HashMap<>();
  private final Map<String, Calendar> _countryMap = new HashMap<>();

  //-------------------------------------------------------------------------
  /**
   * Gets a convention by name.
   * Matching is case insensitive.
   *
   * @param name  the name, not null
   * @return the convention, not null
   * @throws IllegalArgumentException if not found
   */
  @FromString
  public static Calendar of(final String name) {
    final Calendar result = CalendarFactory.INSTANCE.getCalendar(name);
    if (result == null) {
      throw new IllegalArgumentException("Unknown Calendar: " + name);
    }
    return result;
  }

  //-------------------------------------------------------------------------
  /**
   * Creates the factory.
   */
  private CalendarFactory() {
    loadCalendarInstances();
    loadCountryDefinitions();
  }

  private void loadCalendarInstances() {
    final ResourceBundle calendars = ResourceBundle.getBundle(Calendar.class.getName());
    for (final String calendarName : calendars.keySet()) {
      try {
        String uri = null;
        String clazzName = calendars.getString(calendarName);
        if (clazzName.indexOf(':') > 0) {
          uri = clazzName.substring(clazzName.indexOf(':') + 1);
          final URL url = getClass().getClassLoader().getResource(uri);
          if (url != null) {
            uri = url.toString();
          }
          clazzName = clazzName.substring(0, clazzName.indexOf(':'));
        }
        final Class<? extends Calendar> clazz = Class.forName(clazzName).asSubclass(Calendar.class);
        final Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        int noArgConstructor = -1;
        int nameConstructor = -1;
        int nameURIConstructor = -1;
        for (int i = 0; i < constructors.length; i++) {
          final Class<?>[] params = constructors[i].getParameterTypes();
          if (params.length == 0) {
            noArgConstructor = i;
          } else if (params.length == 1) {
            if (params[0].equals(String.class)) {
              nameConstructor = i;
            }
          } else if (params.length == 2) {
            if (params[0].equals(String.class) && params[1].equals(String.class)) {
              nameURIConstructor = i;
            }
          }
        }
        Calendar instance;
        if ((uri != null) && (nameURIConstructor >= 0)) {
          instance = (Calendar) constructors[nameURIConstructor].newInstance(calendarName, uri);
        } else if (nameConstructor >= 0) {
          instance = (Calendar) constructors[nameConstructor].newInstance(calendarName);
        } else if (noArgConstructor >= 0) {
          instance = (Calendar) constructors[noArgConstructor].newInstance();
        } else {
          throw new OpenGammaRuntimeException("No suitable constructor for '" + calendarName + "'");
        }
        _calendarMap.put(calendarName.toLowerCase(), instance);
      } catch (final InstantiationException ex) {
        throw new OpenGammaRuntimeException("Error initialising Calendars", ex);
      } catch (final IllegalAccessException ex) {
        throw new OpenGammaRuntimeException("Error initialising Calendars", ex);
      } catch (final ClassNotFoundException ex) {
        throw new OpenGammaRuntimeException("Error initialising Calendars", ex);
      } catch (final IllegalArgumentException ex) {
        throw new OpenGammaRuntimeException("Error initialising Calendars", ex);
      } catch (final InvocationTargetException ex) {
        throw new OpenGammaRuntimeException("Error initialising Calendars", ex);
      }
    }
  }

  private void loadCountryDefinitions() {
    final ResourceBundle countries = ResourceBundle.getBundle("com.opengamma.financial.convention.calendar.Country");
    for (final String countryCode : countries.keySet()) {
      final String calendarName = countries.getString(countryCode);
      final Calendar calendar = getCalendar(calendarName);
      if (calendar == null) {
        throw new OpenGammaRuntimeException("Cannot find calendar '" + calendarName + "' for country '" + countryCode + "'");
      }
      _countryMap.put(countryCode, calendar);
    }
  }

  // -------------------------------------------------------------------------
  /**
   * Gets a working day calendar by name.
   * Matching is case insensitive.
   *
   * @param name  the name, not null
   * @return the convention, null if not found
   */
  @FromString
  public Calendar getCalendar(final String name) {
    return _calendarMap.get(name.toLowerCase(Locale.ENGLISH));
  }

  /**
   * Gets a working day calendar by 3-letter country code.
   *
   * @param country  the country code, not null
   * @return the convention, null if not found
   */
  public Calendar getCalendarByCountry(final String country) {
    return _countryMap.get(country);
  }

}
TOP

Related Classes of com.opengamma.financial.convention.calendar.CalendarFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.