javax.time.calendar
Class CalendricalRule<T>

java.lang.Object
  extended by javax.time.calendar.CalendricalRule<T>
Type Parameters:
T - the underlying type representing the data, typically a Calendrical, Number or Enum, must be immutable, should be comparable
All Implemented Interfaces:
java.io.Serializable, java.util.Comparator<Calendrical>
Direct Known Subclasses:
DateTimeRule

public abstract class CalendricalRule<T>
extends java.lang.Object
implements java.util.Comparator<Calendrical>, java.io.Serializable

A rule defining how a single well-defined calendrical element operates.

Calendrical rules may define fields like day-of-month, combinations like date-time, or other related types like time-zone.

Each rule uses an underlying type to represent the data. This is captured in the generic type of the rule. The underlying type is reified and made available via getType(). It is expected, but not enforced, that the underlying type is Comparable.

This is an abstract class and must be implemented with care to ensure other classes in the framework operate correctly. All instantiable subclasses must be final, immutable and thread-safe. Subclasses should implement equals and hashCode. The subclass is also fully responsible for serialization as all fields in this class are transient. The subclass must use readResolve to replace the deserialized class with a valid one created via a constructor.

Author:
Michael Nascimento Santos, Stephen Colebourne
See Also:
Serialized Form

Constructor Summary
protected CalendricalRule(java.lang.Class<T> type, java.lang.String name)
          Constructor used to create a rule.
 
Method Summary
 int compare(Calendrical cal1, Calendrical cal2)
          Compares two Calendrical implementations based on the value of this rule extracted from each calendrical.
protected  T deriveFrom(CalendricalEngine engine)
          Override point to derive the value for this rule from the merger.
 java.lang.String getName()
          Gets the name of the rule.
 java.lang.Class<T> getType()
          Gets the type of the rule, which is a reification of the generic type.
 T getValue(Calendrical calendrical)
          Gets the value of this rule from the specified calendrical returning null if the value cannot be returned.
 T getValueChecked(Calendrical calendrical)
          Gets the value of the rule from the specified calendrical throwing an exception if the rule cannot be returned.
protected  void merge(CalendricalEngine engine, java.util.List<CalendricalEngine> engines)
          Override point to affect the merging process.
 T reify(java.lang.Object value)
          Returns the input value cast to the correct generic type.
 java.lang.String toString()
          Outputs this rule as a String, using the name.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface java.util.Comparator
equals
 

Constructor Detail

CalendricalRule

protected CalendricalRule(java.lang.Class<T> type,
                          java.lang.String name)
Constructor used to create a rule.

Parameters:
type - the reified class, not null
name - the name of the type, not null
Method Detail

getName

public final java.lang.String getName()
Gets the name of the rule.

Implementations should use the name that best represents themselves. If the rule represents a field, then the form 'UnitOfRange' should be used. Otherwise, use the simple class name of the generic type, such as 'ZoneOffset'. For debugging reasons, the name should be as unique as possible.

Returns:
the name of the rule, not null

getType

public final java.lang.Class<T> getType()
Gets the type of the rule, which is a reification of the generic type.

Each rule uses an underlying type to represent the data. This is captured in the generic type of the rule. Since the generic implementation is Java is limited to the compiler, the underlying type has been reified and made available through this method. It is expected, but not enforced, that the underlying type is Comparable.

Returns:
the reified type of values of the rule, not null

reify

public final T reify(java.lang.Object value)
Returns the input value cast to the correct generic type.

Each rule uses an underlying type to represent the data. This is captured in the generic type of the rule. Since the generic implementation is Java is limited to the compiler, the underlying type has been reified which allows this method to validate the generic type fully. The implementation simply returns the input value typed as the generic type.

Parameters:
value - the value to reify, may be null
Returns:
the type-cast input value, may be null
Throws:
java.lang.ClassCastException - if the value is not of the reified type

getValue

public final T getValue(Calendrical calendrical)
Gets the value of this rule from the specified calendrical returning null if the value cannot be returned.

This method simply queries the calendrical.

Parameters:
calendrical - the calendrical to get the field value from, not null
Returns:
the value of the field, null if unable to extract the field

getValueChecked

public final T getValueChecked(Calendrical calendrical)
Gets the value of the rule from the specified calendrical throwing an exception if the rule cannot be returned.

This convenience method uses getValue(Calendrical) to find the value and then ensures it isn't null.

Parameters:
calendrical - the calendrical to get the field value from, not null
Returns:
the value of the field, not null
Throws:
CalendricalException - if the rule cannot be extracted

merge

protected void merge(CalendricalEngine engine,
                     java.util.List<CalendricalEngine> engines)
Override point to affect the merging process.

This method is called during merging on the rule associated with each semi-normalized merger. The implementation has the opportunity to adjust the mergers, potentially handling any conflicts. For example, the OffsetTime rule could check to see if there is an OffsetDate with a conflicting offset, and adjust the time accordingly.

Parameters:
engine - the engine that was created from an instance of the object associated with this rule, not null
engines - all the engines being processed, unmodifiable, but containing modifiable mergers, not null

deriveFrom

protected T deriveFrom(CalendricalEngine engine)
Override point to derive the value for this rule from the merger.

This is part of the merge process, which exists to extract the maximum information possible from a set calendrical data. Before this method is called, the engine will be normalized, which ensures that any fields that can be converted to objects will have been. Thus this method is primarily used to create objects from the normalized form.

A typical implementation will check the objects and determine if the value can be derived from them. For example, a LocalDateTime can be derived from a LocalDate and a LocalTime. In general, only the objects should be used for derivation, as derivation from any remaining fields is handled directly by the engine.

Implementations should avoid throwing exceptions and use the merger error mechanism instead. It is strongly recommended to treat the data in the engine as immutable.

This implementation uses CalendricalEngine.getFieldDerived(javax.time.calendar.DateTimeRule, boolean)

Parameters:
engine - the engine to derive from, not null
Returns:
the derived field, null if unable to derive

compare

public int compare(Calendrical cal1,
                   Calendrical cal2)
Compares two Calendrical implementations based on the value of this rule extracted from each calendrical.

This implements the Comparator interface and allows any two Calendrical implementations to be compared using this rule. The comparison is based on the result of calling Calendrical.get(javax.time.calendar.CalendricalRule) on each calendrical, and comparing those values.

For example, to sort a list into year order when the list may contain any mixture of calendricals, such as a LocalDate, YearMonth and ZonedDateTime:

  List list = ...
  Collections.sort(list, ISODateTimeRule.YEAR);
 
If the value of this rule cannot be obtained from a calendrical, then an exception is thrown.

If the underlying type of this rule does not implement Comparable then an exception will be thrown.

Specified by:
compare in interface java.util.Comparator<Calendrical>
Parameters:
cal1 - the first calendrical to compare, not null
cal2 - the second calendrical to compare, not null
Returns:
the comparator result, negative if first is less, positive if first is greater, zero if equal
Throws:
java.lang.NullPointerException - if either input is null
java.lang.ClassCastException - if this rule has a type that is not comparable
java.lang.IllegalArgumentException - if this rule cannot be extracted from either input parameter

toString

public java.lang.String toString()
Outputs this rule as a String, using the name.

Overrides:
toString in class java.lang.Object
Returns:
a string representation of this rule, not null