com.opengamma.financial.convention.calendar.XMLCalendarLoader.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.financial.convention.calendar.XMLCalendarLoader.java

Source

/**
 * 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.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.lang.Validate;
import org.threeten.bp.LocalDate;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.opengamma.OpenGammaRuntimeException;

/**
 * Populates an {@code ExceptionCalendar} with working and non-working days from
 * an XML data source.
 */
public class XMLCalendarLoader {

    private static final String TAG_WORKING_DAYS = "WorkingDays";
    private static final String TAG_NON_WORKING_DAYS = "NonWorkingDays";
    private static final String TAG_DATE = "Date";

    /**
     * The state of the parser.
     */
    private static enum ParserState {
        WORKING_DAYS, NON_WORKING_DAYS, OTHER;
    }

    /**
     * The source URI.
     */
    private final String _sourceDataURI;

    /**
     * Creates an instance using the URI of the XML file.
     * @param sourceDataUri  the source URI, not null
     */
    public XMLCalendarLoader(final String sourceDataUri) {
        Validate.notNull(sourceDataUri, "URI");
        _sourceDataURI = sourceDataUri;
    }

    // -------------------------------------------------------------------------
    /**
     * Gets the source data URI.
     * @return the URI, not null
     */
    protected String getSourceDataURI() {
        return _sourceDataURI;
    }

    /**
     * Throws a suitable exception.
     * @param th  the error, not null
     * @return the exception to throw, not null
     */
    private OpenGammaRuntimeException wrap(final Throwable th) {
        return new OpenGammaRuntimeException("Unable to populate calendar from XML", th);
    }

    /**
     * Populate the specified working day calendar from the XML file.
     * @param calendar  the calendar to populate, not null
     */
    public void populateCalendar(final ExceptionCalendar calendar) {
        final SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            final SAXParser parser = factory.newSAXParser();
            parser.parse(getSourceDataURI(), new DefaultHandler() {
                private ParserState _state = ParserState.OTHER;
                private String _innerText;

                @Override
                public void startElement(final String uri, final String localName, final String qName,
                        final Attributes attributes) {
                    switch (_state) {
                    case OTHER:
                        if (qName.equalsIgnoreCase(TAG_WORKING_DAYS)) {
                            _state = ParserState.WORKING_DAYS;
                        } else if (qName.equalsIgnoreCase(TAG_NON_WORKING_DAYS)) {
                            _state = ParserState.NON_WORKING_DAYS;
                        }
                        break;
                    }
                }

                @Override
                public void characters(final char[] ch, final int start, final int length) {
                    _innerText = new String(ch, start, length);
                }

                @Override
                public void endElement(final String uri, final String localName, final String qName) {
                    switch (_state) {
                    case WORKING_DAYS:
                        if (qName.equalsIgnoreCase(TAG_DATE)) {
                            calendar.addWorkingDay(LocalDate.parse(_innerText));
                        } else if (qName.equalsIgnoreCase(TAG_WORKING_DAYS)) {
                            _state = ParserState.OTHER;
                        }
                        break;
                    case NON_WORKING_DAYS:
                        if (qName.equalsIgnoreCase(TAG_DATE)) {
                            calendar.addNonWorkingDay(LocalDate.parse(_innerText));
                        } else if (qName.equalsIgnoreCase(TAG_NON_WORKING_DAYS)) {
                            _state = ParserState.OTHER;
                        }
                        break;
                    }
                }
            });
        } catch (final ParserConfigurationException ex) {
            throw wrap(ex);
        } catch (final SAXException ex) {
            throw wrap(ex);
        } catch (final IOException ex) {
            throw wrap(ex);
        }
    }

}