org.osframework.contract.date.fincal.definition.FinancialCalendar.java Source code

Java tutorial

Introduction

Here is the source code for org.osframework.contract.date.fincal.definition.FinancialCalendar.java

Source

/*
 * File: FinancialCalendar.java
 * 
 * Copyright 2012 OSFramework Project.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.osframework.contract.date.fincal.definition;

import java.io.Serializable;
import java.util.Collections;
import java.util.Currency;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlIDREF;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.osframework.contract.date.fincal.ImmutableEntity;

/**
 * Holiday calendar definition for a particular financial market. An instance of
 * this class is an iterable collection of <code>HolidayDefinition</code>s
 * representing the financial ("bank") holidays observed in the associated
 * market's country or economic zone.
 * <p>
 * The {@link #id} property of a <code>FinancialCalendar</code> object is not
 * arbitrary: valid values correspond to the financial calendar codes specified
 * by <b>financialcalendar.com</b>, the <i>de facto</i> authoritative source of
 * calendar data used by financial institutions worldwide.
 * </p>
 * <p>An instance of this class can provide an immutable and thread-safe
 * version of itself.</p>
 * 
 * @author <a href="mailto:dave@osframework.org">Dave Joyce</a>
 * @see <a href="http://www.financialcalendar.com/Data/Holidays/Coverage">
   Coverage - Financial Calendar</a>
 */
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlType(name = "calendar", propOrder = { "description", "centralBank", "holidayDefinitions" })
public class FinancialCalendar
        implements Serializable, Iterable<HolidayDefinition>, ImmutableEntity<FinancialCalendar> {

    /**
     * Serializable UID.
     */
    private static final long serialVersionUID = 6295632117301841003L;

    private String id;
    private String description;
    private CentralBank centralBank;
    private Set<HolidayDefinition> holidayDefinitions = new HashSet<HolidayDefinition>();

    /**
     * Default constructor.
     */
    public FinancialCalendar() {
    }

    /**
     * Constructor. Holiday definitions passed to this constructor are copied to
     * an new collection.
     *
     * @param id unique identifier for this instance
     * @param description short description of this calendar definition
     * @param centralBank central bank which governs this calendar's holiday definitions
     * @param holidayDefinitions collection of holiday definitions which comprise this calendar
     * @throws IllegalArgumentException if centralBank or holidayDefinitions is null
     */
    public FinancialCalendar(final String id, final String description, final CentralBank centralBank,
            final Set<HolidayDefinition> holidayDefinitions) {
        this();
        this.setId(id);
        this.setDescription(description);
        this.setCentralBank(centralBank);
        this.setHolidayDefinitions(holidayDefinitions);
    }

    /**
     * @return unique identifier for this instance
     */
    @XmlID
    @XmlAttribute(name = "id", required = true)
    public String getId() {
        return id;
    }

    /**
     * Set unique identifier for this financial calendar.
     * 
     * @param id unique identifier for this instance
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return short description of this calendar definition
     */
    @XmlElement(name = "description", required = true)
    public String getDescription() {
        return description;
    }

    /**
     * Set description of this financial calendar.
     * 
     * @param description short description of this calendar definition
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * @return central bank which governs this calendar's holiday definitions
     */
    @XmlIDREF
    @XmlAttribute(name = "centralBank", required = true)
    public CentralBank getCentralBank() {
        return centralBank;
    }

    /**
     * Set central bank of this financial calendar.
     * 
     * @param centralBank central bank which governs this calendar's holiday
     *                    definitions
     * @throws IllegalArgumentException if centralBank is null
     */
    public void setCentralBank(CentralBank centralBank) {
        if (null == centralBank) {
            throw new IllegalArgumentException("CentralBank argument cannot be null");
        }
        this.centralBank = centralBank;
    }

    /**
     * @return currency with which this calendar definition is associated
     */
    @XmlTransient
    public Currency getCurrency() {
        return (null == centralBank) ? null : centralBank.getCurrency();
    }

    /**
     * @return holiday definitions referenced by this financial calendar
     */
    @XmlElementWrapper(name = "holidayDefinitions", required = true)
    @XmlElements({ @XmlElement(name = "ref", type = HolidayDefinition.class) })
    @XmlIDREF
    public Set<HolidayDefinition> getHolidayDefinitions() {
        return holidayDefinitions;
    }

    /**
     * Set holiday definitions to be referenced by this financial calendar.
     * 
     * @param holidayDefinitions holiday definitions referenced by this
     *                           financial calendar
     * @throws IllegalArgumentException if holidayDefinitions is null
     */
    public void setHolidayDefinitions(Set<HolidayDefinition> holidayDefinitions) {
        if (null == holidayDefinitions) {
            throw new IllegalArgumentException("Set argument cannot be null");
        }
        this.holidayDefinitions.clear();
        this.holidayDefinitions.addAll(holidayDefinitions);
    }

    /**
     * Add a holiday definition to this financial calendar.
     * 
     * @param holidayDefinition holiday definition to be added
     * @throws IllegalArgumentException if holidayDefinition is null
     */
    public void addHolidayDefinition(HolidayDefinition holidayDefinition) {
        if (null == holidayDefinition) {
            throw new IllegalArgumentException("holidayDefinition argument cannot be null");
        }
        this.holidayDefinitions.add(holidayDefinition);
    }

    /**
     * Remove a holiday definition from this financial calendar.
     * 
     * @param holidayDefinition holiday definition to be removed
     * @throws IllegalArgumentException if holidayDefinition is null
     */
    public void removeHolidayDefinition(HolidayDefinition holidayDefinition) {
        if (null == holidayDefinition) {
            throw new IllegalArgumentException("holidayDefinition argument cannot be null");
        }
        this.holidayDefinitions.remove(holidayDefinition);
    }

    /**
     * Determine if this calendar contains the specified holiday definition.
     * 
     * @param hd holiday definition to be checked
     * @return <code>true</code> if this calendar contains the holiday
     *         definition, <code>false</code> otherwise
     */
    public boolean contains(HolidayDefinition hd) {
        return holidayDefinitions.contains(hd);
    }

    /**
     * @return iterator over the holiday definitions in this financial calendar
     */
    public Iterator<HolidayDefinition> iterator() {
        return holidayDefinitions.iterator();
    }

    /**
     * @return number of holiday definitions in this calendar
     */
    public int size() {
        return holidayDefinitions.size();
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }

    public FinancialCalendar toImmutable() {
        return new ImmutableFinancialCalendar(this.id, this.description, this.centralBank, this.holidayDefinitions);
    }

    @XmlTransient
    public boolean isImmutable() {
        return (this instanceof ImmutableFinancialCalendar);
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(id).append(description).append(centralBank).append(holidayDefinitions)
                .toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
        boolean result;
        if (this == obj) {
            result = true;
        } else if (obj instanceof FinancialCalendar) {
            final FinancialCalendar other = (FinancialCalendar) obj;
            result = new EqualsBuilder().append(id, other.id).append(description, other.description)
                    .append(centralBank, other.centralBank).append(holidayDefinitions, other.holidayDefinitions)
                    .isEquals();
        } else {
            result = false;
        }
        return result;
    }

    /**
     * Private immutable subclass of FinancialCalendar. This class is final; it
     * is intended solely for instantiation by
     * {@link FinancialCalendar#toImmutable()}.
     *
     * @author <a href="mailto:dave@osframework.org">Dave Joyce</a>
     */
    @XmlTransient
    private final class ImmutableFinancialCalendar extends FinancialCalendar {

        /**
         * Serializable UID.
         */
        private static final long serialVersionUID = -7685175750981328587L;

        /**
         * Cached hash value for this instance.
         */
        private volatile transient int hashCode;

        /**
         * Constructor. Accepts all fields as arguments, using the parent
         * class's setters for initialization.
         * 
         * @param id
         * @param description
         * @param centralBank
         * @param holidayDefinitions
         */
        ImmutableFinancialCalendar(final String id, final String description, final CentralBank centralBank,
                final Set<HolidayDefinition> holidayDefinitions) {
            super();
            super.setId(id);
            super.setDescription(description);
            super.setCentralBank(centralBank);
            super.setHolidayDefinitions(holidayDefinitions);
        }

        /**
         * Overridden method to prevent mutability of this instance.
         * 
         * @throws UnsupportedOperationException
         */
        @Override
        public final void setId(String id) {
            throw new UnsupportedOperationException(DEFAULT_EXCEPTION_MSG);
        }

        /**
         * Overridden method to prevent mutability of this instance.
         * 
         * @throws UnsupportedOperationException
         */
        @Override
        public final void setDescription(String description) {
            throw new UnsupportedOperationException(DEFAULT_EXCEPTION_MSG);
        }

        /**
         * Overridden method to prevent mutability of this instance.
         * 
         * @throws UnsupportedOperationException
         */
        @Override
        public final void setCentralBank(CentralBank centralBank) {
            throw new UnsupportedOperationException(DEFAULT_EXCEPTION_MSG);
        }

        /**
         * Overridden method to prevent mutability of this instance.
         */
        @Override
        public final Set<HolidayDefinition> getHolidayDefinitions() {
            return Collections.unmodifiableSet(super.getHolidayDefinitions());
        }

        /**
         * Overridden method to prevent mutability of this instance.
         * 
         * @throws UnsupportedOperationException
         */
        @Override
        public final void setHolidayDefinitions(Set<HolidayDefinition> holidayDefinitions) {
            throw new UnsupportedOperationException(DEFAULT_EXCEPTION_MSG);
        }

        /**
         * Overridden method to prevent mutability of this instance.
         * 
         * @throws UnsupportedOperationException
         */
        @Override
        public final void addHolidayDefinition(HolidayDefinition holidayDefinition) {
            throw new UnsupportedOperationException(DEFAULT_EXCEPTION_MSG);
        }

        /**
         * Overridden method to prevent mutability of this instance.
         * 
         * @throws UnsupportedOperationException
         */
        @Override
        public final void removeHolidayDefinition(HolidayDefinition holidayDefinition) {
            throw new UnsupportedOperationException(DEFAULT_EXCEPTION_MSG);
        }

        /**
         * @return unmodifiable iterator over the holiday definitions in this
         *         financial calendar
         */
        @Override
        public final Iterator<HolidayDefinition> iterator() {
            return this.getHolidayDefinitions().iterator();
        }

        /**
         * This implementation simply returns <code>this</code>.
         */
        @Override
        public final FinancialCalendar toImmutable() {
            return this;
        }

        @Override
        public int hashCode() {
            if (0 == hashCode) {
                hashCode = new HashCodeBuilder().append(id).append(description).append(centralBank)
                        .append(holidayDefinitions).toHashCode();
            }
            return hashCode;
        }
    }

}