/* * Copyright (c) 2012, 2013, Credit Suisse (Anatole Tresch), Werner Keil. * * 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.javamoney.validity; import java.io.Serializable; import java.util.Calendar; /** * This base class models a validity of an item T related to a timeline. Hereby * a validity may be undefined, when it starts or when it ends. * <p> * This class is immutable, thread-safe and {@link Serializable}. Also it * implements {@link Comparable}. * * @author Anatole Tresch * * @param <T> * the item type, e.g. a Region */ public class ValidityInfo<T> implements Serializable, Comparable<ValidityInfo<T>> { /** * Serial version UID. */ private static final long serialVersionUID = 1258686258819748870L; /** The item for which this ValidityInfo is for. */ private final T item; /** * The starting UTC timestamp for the validity period, or null. */ private final Long from; /** * The ending UTC timestamp for the validity period, or null. */ private final Long to; /** * The source that provides this validity data. */ private final String validitySource; /** * The target timezone id of this validity instance, allowing to restore the * correct local date. */ private final String targetTimezoneId; /** * The type of validity. */ private ValidityType validityType; /** * Additional user data associated with that {@link ValidityInfo} instance. */ private Object userData; /** * Creates an instance of ValidityInfo. * * @param item * the item, not null. * @param validitySource * the validity source. * @param from * the calendar instance, defining the start of the validity * range. * @param to * the calendar instance, defining the end of the validity range. */ public ValidityInfo(T item, ValidityType validityType, String validitySource, Calendar from, Calendar to, String targetTimezoneId, Object userData) { if (item == null) { throw new IllegalArgumentException("Currency required."); } if (validityType == null) { throw new IllegalArgumentException("ValidityType required."); } if (validitySource == null) { throw new IllegalArgumentException("Validity Source required."); } this.item = item; this.validityType = validityType; this.validitySource = validitySource; if (from != null) { this.from = from.getTimeInMillis(); } else { this.from = null; } if (to != null) { this.to = to.getTimeInMillis(); } else { this.to = null; } this.targetTimezoneId = targetTimezoneId; this.userData = this.userData = userData; } /** * Creates an instance of ValidityInfo. * * @param item * the item, not null. * @param validitySource * the validity source. * @param from * the UTC timestamp, defining the start of the validity range. * @param to * the UTC timestamp, defining the end of the validity range. */ public ValidityInfo(T item, ValidityType validityType, String validitySource, Long from, Long to, String targetTimezoneId, Object userData) { if (item == null) { throw new IllegalArgumentException("Currency required."); } if (validityType == null) { throw new IllegalArgumentException("ValidityType required."); } if (validitySource == null) { throw new IllegalArgumentException("Validity Source required."); } this.item = item; this.validityType = validityType; this.validitySource = validitySource; this.from = from; this.to = to; this.targetTimezoneId = targetTimezoneId; this.userData = userData; } /** * Returns the type of validity this instance represents. * * @see ValidityType * @return the validity type, never {@code null}. */ public ValidityType getValidityType() { return this.validityType; } /** * Access the user data. * * @return the user data associated with this instance, or null. */ @SuppressWarnings("unchecked") public Object getUserData() { return (T) userData; } /** * Method to quickly determine if a validity is not defined, meaning * {@code from} as well as {@code to} is {@code null}. * * @return {@code true} if the validity is undefined. */ public boolean isUndefined() { return from == null && to == null; } /** * Method to quickly determine if a validity is valid for the current * timestamp. A Validity is considered valid, if all the following is * {@code true}: * <ul> * <li><@code from == null || from <= current UTC timestamp}</li> * <li><@code to == null || to >= current UTC timestamp}</li> * </ul> * * @return {@code true} if the validity is currently valid. */ public boolean isValid() { long ts = System.currentTimeMillis(); return (from == null || from <= ts) && (to == null || to >= ts); } /** * Method to easily check if the {@code from} is not {@code null}. * * @return {@code true} if {@code from} is not {@code null}. */ public boolean isLowerBound() { return from != null; } /** * Method to easily check if the {@code from} is not {@code null}. * * @return {@code true} if {@code from} is not {@code null}. */ public boolean isUpperBound() { return to != null; } /** * Access the item for which the validity is defined. * * @return the item, never null. */ public T getItem() { return item; } /** * Access the starting UTC timestamp from which the item T is valid, related * to R. * * @return the starting UTC timestamp, or null. */ public Long getFromTimeInMillis() { if (from != null) { return from; } return null; } /** * Access the ending UTC timestamp until the item T is valid, related to R. * * @return the ending UTC timestamp, or null. */ public Long getToTimeInMillis() { if (to != null) { return to; } return null; } /** * Return the target time zone for the given validity, which allows to * distinct validities that may embrace several timezones (e.g. for * regions). Additionally the timezone, combined with the UTC timestamp * allows to reconstruct the local date (e.g. within the according * {@link Region}). * * @return the target timezone id of this validity, never {@code null}. */ public String getTargetTimezoneId() { return targetTimezoneId; } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((from == null) ? 0 : from.hashCode()); result = prime * result + ((item == null) ? 0 : item.hashCode()); result = prime * result + ((to == null) ? 0 : to.hashCode()); result = prime * result + ((validitySource == null) ? 0 : validitySource.hashCode()); return result; } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } @SuppressWarnings("rawtypes") ValidityInfo other = (ValidityInfo) obj; if (from == null) { if (other.from != null) { return false; } } else if (!from.equals(other.from)) { return false; } if (item == null) { if (other.item != null) { return false; } } else if (!item.equals(other.item)) { return false; } if (to == null) { if (other.to != null) { return false; } } else if (!to.equals(other.to)) { return false; } if (validitySource == null) { if (other.validitySource != null) { return false; } } else if (!validitySource.equals(other.validitySource)) { return false; } return true; } /* * (non-Javadoc) * * @see java.lang.Comparable#compareTo(java.lang.Object) */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public int compareTo(ValidityInfo other) { if (this == other) { return 0; } if (other == null) { return -1; } int compare = 0; if (item instanceof Comparable) { if (item == null) { if (other.item != null) { compare = 1; } } else { if (other.item == null) { compare = -1; } else { compare = ((Comparable) item).compareTo(other.item); } } } if (from == null) { if (other.from != null) { compare = 1; } } else { if (other.from == null) { compare = -1; } else { if (other.from == null) { compare = -1; } else { compare = ((Comparable) from).compareTo(other.from); } } } if (compare == 0) { if (to == null) { if (other.to != null) { compare = 1; } } else { if (other.to == null) { compare = -1; } else { compare = ((Comparable) to).compareTo(other.to); } } } if (compare == 0) { if (validitySource == null) { if (other.validitySource != null) { compare = 1; } } else { if (other.validitySource == null) { compare = -1; } else { compare = ((Comparable) validitySource) .compareTo(other.validitySource); } } } return compare; } }