Evaluating Software Design Patterns
— the "Gang of Four" patterns implemented in Java 6

dk.rode.thesis.bridge
Class SequenceValueCollection<E extends Serializable,C extends Collection<E>>

java.lang.Object
  extended by dk.rode.thesis.bridge.SequenceValueCollection<E,C>
Type Parameters:
E - The type of serializable values stored in this value collection.
C - The internal collection type used by this value collection.
All Implemented Interfaces:
SequenceValueGenerator<E>, Copyable<SequenceValueGenerator<E>>, Stringable<SequenceValueGenerator<E>>
Direct Known Subclasses:
SequenceValueArrayList, SequenceValueSet

@Participant(value="Implementor")
public abstract class SequenceValueCollection<E extends Serializable,C extends Collection<E>>
extends Object
implements SequenceValueGenerator<E>

A sequence value collection is a finite collection of non-null sequence values that can be used as the implementation for a sequence abstraction.

Besides the inherited properties from SequenceValueGenerator, any sequence value collection will contain serializable values only. This is a requirement in order to achieve deep cloning in a generic fashion.

Implementation notes:
By demanding that the type of contained values in this collection are serializable, i.e. <E extends Serializable>, deep copying becomes easy for any value collection implementation. To copy a given collection, the java.util.Collection type determined by the type parameter C is simply serialized, then deserialized to yield a new instance with new value instances as well. The structure of the values in the original collection are adhered to as serialization maintains relative object identity in serialized object graphs. Hence, singleton objects such as enumerations will not be copied, while actual values will be.

It also ensures that standard value types such as Integer, Long, Date, etc, can be used as values, which would not be the case if the the type parameter bound on E had been java.lang.Cloneable instead. However, the work in copying a value collection is proportional with the number of values contained, and is thus more expensive the larger the collection is! But, this is no different than if the values had been cloned.

Author:
Gunni Rode / rode.dk

Field Summary
protected  int number
          The number of the the last value delivered by either SequenceValueGenerator.first(), SequenceValueGenerator.get(), or SequenceValueGenerator.get(int).
protected  Class<E> type
          The type of the sequence values stored in this collection.
protected  C values
          The actual collection used to store the sequence values.
 
Constructor Summary
protected SequenceValueCollection(Class<E> type, C values, int number)
          Creates this collection of values to use the actual sequence values supplied in values, each having the type supplied as type.
 
Method Summary
protected  boolean checkNumber(int number, boolean fail)
          Ensures the the number of a given value generated by this values is legal.
abstract  SequenceValueCollection<E,C> copy()
          Performs a deep copy of this generator.
 boolean equals(Object object)
          Returns true if object is a SequenceValueCollection instance that delivers the same type of values as this collection, has the same size, has the same ordered, sorted, and duplicate properties, and contain the same equivalent values adhering to the properties just listed.
 StringablePolicy<? super SequenceValueGenerator<E>> getStringablePolicy(StringablePolicy<? super SequenceValueGenerator<E>> policy)
          Always return a non-null policy: policy is not null: policy is returned.
 Class<E> getValueType()
          Returns the actual type of the values generated by this generator.
 int hashCode()
          Returns the hash code of this value collection.
 int number()
          Returns the number of the the last value generated by either SequenceValueGenerator.first(), SequenceValueGenerator.get(), or SequenceValueGenerator.get(int).
 int size()
          Returns the number of values that can be generated by this generator in total, excluding re-generation of values after a call to SequenceValueGenerator.first().
 Collection<? super E> toCollection(Collection<? super E> collection)
          Adds all values in this value collection to the collection supplied as collection.
 String toString()
          Returns the string representation of this collection.
 CharSequence toString(StringablePolicy<? super SequenceValueGenerator<E>> policy)
          Returns a char sequence representation of this stringable object using the format determined by policy or the default policy in case policy is null.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface dk.rode.thesis.bridge.SequenceValueGenerator
duplicates, first, get, get, numberOf, ordered, sorted
 

Field Detail

number

protected int number
The number of the the last value delivered by either SequenceValueGenerator.first(), SequenceValueGenerator.get(), or SequenceValueGenerator.get(int).

Range: 1 (0) <= number <= size()


type

protected final Class<E extends Serializable> type
The type of the sequence values stored in this collection.

Never null.


values

protected final C extends Collection<E> values
The actual collection used to store the sequence values.

Never null.

Constructor Detail

SequenceValueCollection

protected SequenceValueCollection(Class<E> type,
                                  C values,
                                  int number)
Creates this collection of values to use the actual sequence values supplied in values, each having the type supplied as type.

The next value to return by SequenceValueGenerator.get() is the value that is the number'th value in this collection. It is the responsibility of sub-classes to initialises this value collection accordingly.

Modifying values externally will affect this collection and should not be performed. The result of doing so is undefined - but never good.

values must not contain null entries. If it does, the sequence abstraction using this collection will generate an internal error when that entry is returned by this collection!

Parameters:
type - The type of values stored in this collection; cannot be null.
values - The actual Collection instance storing the sequence values; cannot be null, empty, or contain null values.
number - The number pointing the the number'th value to be returned by the next call to SequenceValueGenerator.get().
Throws:
NullPointerException - If either argument is null.
IllegalArgumentException - If values is empty, or contain a null value, or if number is illegal.
Method Detail

checkNumber

protected final boolean checkNumber(int number,
                                    boolean fail)
Ensures the the number of a given value generated by this values is legal.

A valid range is: 1 <= number <= size()

Parameters:
number - The number to check.
fail - If true, an exception is thrown if number is illegal, otherwise false is returned. If legal, true is always returned.
Returns:
If fail is false, true if number is valid, false if not.
Throws:
IllegalArgumentException - If fail is true and if number is illegal.

copy

public abstract SequenceValueCollection<E,C> copy()
Performs a deep copy of this generator.

The size, ordered, sorted, and duplicate properties are adhered to by the returned clone.

The work in copying this collection is proportional with the number of values contained, and is thus more expensive the larger this collection is!

Specified by:
copy in interface SequenceValueGenerator<E extends Serializable>
Specified by:
copy in interface Copyable<SequenceValueGenerator<E extends Serializable>>
Returns:
A copy of this value collection; never null.

equals

public boolean equals(Object object)
Returns true if object is a SequenceValueCollection instance that delivers the same type of values as this collection, has the same size, has the same ordered, sorted, and duplicate properties, and contain the same equivalent values adhering to the properties just listed.

Overrides:
equals in class Object
Parameters:
object - The object to test; can be null.
Returns:
True if equal, false if not.

getStringablePolicy

public StringablePolicy<? super SequenceValueGenerator<E>> getStringablePolicy(StringablePolicy<? super SequenceValueGenerator<E>> policy)
Description copied from interface: Stringable
Always return a non-null policy:

  1. policy is not null: policy is returned.

  2. policy is null: a default, non-null policy is returned.

Specified by:
getStringablePolicy in interface Stringable<SequenceValueGenerator<E extends Serializable>>
Parameters:
policy - The supplied policy; can be null.
Returns:
The policy to use; never null.
See Also:
Stringable.toString(StringablePolicy)

getValueType

public final Class<E> getValueType()
Description copied from interface: SequenceValueGenerator
Returns the actual type of the values generated by this generator.

Specified by:
getValueType in interface SequenceValueGenerator<E extends Serializable>
Returns:
The value type; never null.

hashCode

public int hashCode()
Returns the hash code of this value collection.

Overrides:
hashCode in class Object
Returns:
The hash code.

number

public int number()
Description copied from interface: SequenceValueGenerator
Returns the number of the the last value generated by either SequenceValueGenerator.first(), SequenceValueGenerator.get(), or SequenceValueGenerator.get(int).

The number of generated values is reset when first() is invoked, i.e. to a number of one.

Notice, that first and get(int) alter the number count of values generated, which will be reflected in the next invocation of get()!

Range: 1 (0) < number < SequenceValueGenerator.size(), if size != INFINITE.

A number of zero will only occur when no values have been generated yet.

Specified by:
number in interface SequenceValueGenerator<E extends Serializable>
Returns:
The number of the last value generated.

size

public int size()
Description copied from interface: SequenceValueGenerator
Returns the number of values that can be generated by this generator in total, excluding re-generation of values after a call to SequenceValueGenerator.first().

Whether or not the count include duplicates is sub-class specific. If duplicates is false, the size is always equal to the number of unique values generated by this generator.

Specified by:
size in interface SequenceValueGenerator<E extends Serializable>
Returns:
The number of values, or Const.INFINITE if this generator has no (practical) bounds on the number of values it can generate.

toCollection

public Collection<? super E> toCollection(Collection<? super E> collection)
Adds all values in this value collection to the collection supplied as collection.

The insertion order is determined by the addAll method on collection.

Parameters:
collection - The collection; cannot be null.
Returns:
collection; never null.
Throws:
NullPointerException - If collection is null.

toString

public String toString()
Returns the string representation of this collection.

Overrides:
toString in class Object
Returns:
The string representation; never null.

toString

public CharSequence toString(StringablePolicy<? super SequenceValueGenerator<E>> policy)
Description copied from interface: Stringable
Returns a char sequence representation of this stringable object using the format determined by policy or the default policy in case policy is null.

In Foo, a typical implementation of this method could be:

    public CharSequence toString(StringablePolicy<? super Foo> policy) {
      return this.getStringablePolicy(policy).toString(this);
    }
 
There are two approaches to formatting this stringable object into a char sequence representation:

  1. Let policy decide the entire format, as in the Foo example above; or

  2. Use policy to format part of the overall representation, for example letting this method append certain text regardless of the policy used.

Bullet 1) is not always applicable because a given policy implementation may not have access to all required information in its StringablePolicy.toString(Object) method, for example in case multiple stringable objects should be formatted into an overall representation.

In case an implementation uses the approach from bullet 2), care must be take to respect the policy hints so the overall format remains meaningful.

Specified by:
toString in interface Stringable<SequenceValueGenerator<E extends Serializable>>
Parameters:
policy - The policy to dictate the formatting; can be null, in which case the result of toString method is returned.
Returns:
The char sequence representation; never null.
See Also:
StringablePolicy.Type

Gunni Rode / rode.dk

Feel free to use and/or modify the Java 6 source code developed for this thesis AT YOUR OWN RISK, but note that the source code comes WITHOUT ANY — and I do mean WITHOUT ANY — form of warranty WHAT SO EVER!

The original thesis and source code are available at rode.dk/thesis.