Holger's Java API

## com.antelmann.cddb
Class Composition

    java.lang.Object
      com.antelmann.cddb.Composition

All Implemented Interfaces:
  Externalizable, Serializable, Comparable<Composition>

    public class Composition

extends Object
implements Comparable<Composition>, Externalizable

Composition represents a musical opus that can span anything from a single track on a CD to various tracks over multiple CDs recursively including other sub-compositions.

A composition is an abstraction that allows to aggregate Track objects or even multiple compositions to a single composition, so that they can share the same contributions (same artists, same recording, etc.) that serve as attributes for a track. Contributions added to a composition may 'override' a similar contribution that is already associated with its parent composition. Compositions then consist of Track objects (the leaf elements of any composition).

Through the recursive abstraction of Compositions independent from the concept of CDs, one can eliminate most redundancy of defining attributes (in form of Contribution objects) on various levels that then apply to a single track by association.

While a Track can inherit attributes (Contribution objects) from many Compositions, a Composition can only inherit from a single parent, to allow for a clean tree structure. However, Composition objects may share the same Contribution objects with other compositions, even though they may have no other association.

Examples for a composition would be a specific recording of a specific symphony (sharing composer, conductor, orchestra, recording location etc., but put on the same CD with another recording), a single song on a CD with a collection of various songs, a movie soundtrack (that could span many CDs), a standard pop album by an artist, etc.

The title of the composition is used as a unique identifier, i.e. if you have similar compositions (e.g. multiple recordings of a symphony by the same orchestra/conductor that only differ in recording year), you need to find some way to distinguish the compositions in the title.

Any operation on the embedded Set objects must be synchronized externally; note that `setParent(Composition)` also accesses embedded Sets from all parents.

This class requires the Externalizable interface to not throw a NullPointerException when deserializing the HashSet from a Track object containing Composition objects that require already serialized fields when accessing the `hashCode()` method to populate the HashSet in Track. This is the only way to properly ensure that the title is deserialized before

Author:
  Holger Antelmann
See Also:
  `Contribution`, `Track`, Serialized Form

Constructor Summary
`Composition()` only public to be used by the Externalizable interface; this constructor MUST NOT BE USED for other purposes!
`Composition(String title, Genre genre, String description, Composition parent)`

Method Summary
`boolean` `add(Contribution con)`
`boolean` `add(Track t)`
`int` `compareTo(Composition c)` compares by the title for convenient sorting
`boolean` `contains(Contribution con)`
`boolean` `contains(Track t)` only checks for directly added tracks
`CDID` `correspondsToCD()` checks whether this composition directly corresponds to a single CD and returns that CD if that is the case.
`boolean` `equals(Object obj)` checks only for the title that is to be unique
`Set<Contribution>` `getAllContributions()` generates an unmodifiable view of all associated contributions (including contributions from parent Compositions and embedded tracks); this view will not reflect subsequent changes to the actual embedded sets
`Set<Track>` `getAllTracks()` generates an unmodifiable view of all Track objects, including those from children Composition objects; this view will not reflect subsequent changes to the actual embedded sets
`Set<Composition>` `getChildren()` returns an unmodifiable view of the children compositions that add both additional tracks and sub-compositions to this object.
`Set<Contribution>` `getCompositionContributions()` returns an unmodifiable view of only the directly added Contribution objects
`Set<Track>` `getCompositionTracks()` provides an unmodifiable view only of the Track objects directly added to this composition
`String` `getDescription()`
`Genre` `getGenre()`
`Composition` `getParent()` returns the parent composition from which additional contributions are inherited
`Date` `getRecordingDate()`
`int` `getRecordingYear()` convenience method that will calculate the recording year based on the Gregorian calendar; if no date is set, 0 is returned
`String` `getTitle()` returns the title that also serves as the unique identifier for this composition
`int` `hashCode()`
`void` `readExternal(ObjectInput in)` required to support proper de-serialization of the bi-directional relationship
`boolean` `remove(Contribution con)`
`boolean` `remove(Track t)`
`void` `setDescription(String description)`
`void` `setGenre(Genre genre)`
`void` `setParent(Composition newParent)` sets the parent Composition object from which this composition then inherits further contributions
`void` `setRecordingDate(Date date)`
`void` `setRecordingYear(int year)` convenience method that will set the recording date to January 1st of the given year according to the Gregorian calendar
`String` `toString()` returns getTitle()
`void` `writeExternal(ObjectOutput out)` required to support proper serialization of the bi-directional relationship

Methods inherited from class java.lang.Object
`clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

Constructor Detail

### Composition

    public Composition()

  only public to be used by the Externalizable interface; this constructor MUST NOT BE USED for other purposes!

### Composition

    public Composition(String title,
                       Genre genre,
                       String description,
                       Composition parent)

Parameters:
  `title` - must be a non-null unique identifier for this composition

Method Detail

### writeExternal

    public void writeExternal(ObjectOutput out)
                       throws IOException

  required to support proper serialization of the bi-directional relationship

  Specified by:
    `writeExternal` in interface `Externalizable`
  Throws:
    `IOException`

### readExternal

    public void readExternal(ObjectInput in)
                      throws IOException,
                             ClassNotFoundException

  required to support proper de-serialization of the bi-directional relationship

  Specified by:
    `readExternal` in interface `Externalizable`
  Throws:
    `IOException`
    `ClassNotFoundException`

### getParent

    public Composition getParent()

  returns the parent composition from which additional contributions are inherited

  See Also:
    `getChildren()`

### setParent

    public void setParent(Composition newParent)
                   throws RecursiveCycleException

  sets the parent Composition object from which this composition then inherits further contributions

  Throws:
    `RecursiveCycleException` - if the given parent equals this composition or has a parent that equals this

### getChildren

    public Set<Composition> getChildren()

  returns an unmodifiable view of the children compositions that add both additional tracks and sub-compositions to this object. To change the tree structure, use `setParent(Composition)` #see setParent(Composition)

### getTitle

    public String getTitle()

  returns the title that also serves as the unique identifier for this composition

### getDescription

    public String getDescription()

### setDescription

    public void setDescription(String description)

### getGenre

    public Genre getGenre()

### setGenre

    public void setGenre(Genre genre)

### getRecordingDate

    public Date getRecordingDate()

### setRecordingDate

    public void setRecordingDate(Date date)

### setRecordingYear

    public void setRecordingYear(int year)

  convenience method that will set the recording date to January 1st of the given year according to the Gregorian calendar

### getRecordingYear

    public int getRecordingYear()

  convenience method that will calculate the recording year based on the Gregorian calendar; if no date is set, 0 is returned

### contains

    public boolean contains(Contribution con)

### add

    public boolean add(Contribution con)

### remove

    public boolean remove(Contribution con)

### getCompositionContributions

    public Set<Contribution> getCompositionContributions()

  returns an unmodifiable view of only the directly added Contribution objects

### getAllContributions

    public Set<Contribution> getAllContributions()

  generates an unmodifiable view of all associated contributions (including contributions from parent Compositions and embedded tracks); this view will not reflect subsequent changes to the actual embedded sets

  Returns:
    Set of Contribution objects

### correspondsToCD

    public CDID correspondsToCD()

  checks whether this composition directly corresponds to a single CD and returns that CD if that is the case. A composition corresponds to a CD if all directly added tracks of this composition belong to the same CD and if these tracks are all tracks this CD has.

### contains

    public boolean contains(Track t)

  only checks for directly added tracks

### add

    public boolean add(Track t)
                throws IllegalStateException

  Throws:
    `IllegalStateException`

### remove

    public boolean remove(Track t)
                   throws IllegalStateException

  Throws:
    `IllegalStateException`

### getCompositionTracks

    public Set<Track> getCompositionTracks()

  provides an unmodifiable view only of the Track objects directly added to this composition

  Returns:
    Set of Track objects

### getAllTracks

    public Set<Track> getAllTracks()

  generates an unmodifiable view of all Track objects, including those from children Composition objects; this view will not reflect subsequent changes to the actual embedded sets

  Returns:
    Set of Track objects

### hashCode

    public int hashCode()

  Overrides:
    `hashCode` in class `Object`

### compareTo

    public int compareTo(Composition c)

  compares by the title for convenient sorting

  Specified by:
    `compareTo` in interface `Comparable<Composition>`

### equals

    public boolean equals(Object obj)

  checks only for the title that is to be unique

  Overrides:
    `equals` in class `Object`

### toString

    public String toString()

  returns getTitle()

  Overrides:
    `toString` in class `Object`

(c) Holger Antelmann since 2001- all rights reserved (contact: info@antelmann.com)
see www.antelmann.com/developer for further details and available downloads