org.crosswire.jsword.passage

## Class RangedPassage

- java.lang.Object
- - org.crosswire.jsword.passage.AbstractPassage
  - - org.crosswire.jsword.passage.RangedPassage

- All Implemented Interfaces:
    Serializable, Cloneable, Comparable<Key>, Iterable<Key>, Key, Passage, VerseKey<Passage>

      public class RangedPassage
      extends AbstractPassage

  A Passage that is implemented using a TreeSet of VerseRanges. The attributes of the style are:
  - Compact storage of large amounts of data
  - Fast getName()
  - Slow manipulation

  When to normalize()? This is a slow process, but one that is perhaps done bit-by-bit instead of killing everything just to do getName(). The options are:

  - Before every read
  - Before reads with a background thread
  - After every change
  - After every change with a caching scheme
  I'm not sure which will be best. So I'm starting with 1 and optimizing later ... Maybe the best is to allow the user to choose?
  Author:
    Joe Walker
  See Also:
    `The GNU Lesser General Public License for details.`, Serialized Form

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `private static class` | `RangedPassage.VerseIterator` This class is here to prevent users of RangedPassage.iterator() from altering the underlying store and getting us out of sync.
    `private static class` | `RangedPassage.VerseRangeIterator` Loop over the VerseRanges and check that they do not require digging into

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `private static long` | `serialVersionUID` To make serialization work across new versions
    `private Set<VerseRange>` | `store` The place the real data is stored

    - ### Fields inherited from class org.crosswire.jsword.passage.AbstractPassage

      `BITWISE, DISTINCT, listeners, METHOD_COUNT, originalName, RANGED, REF_ALLOWED_DELIMS, REF_OSIS_DELIM, REF_PREF_DELIM, skipNormalization, suppressEvents`

  - ### Constructor Summary

    Constructors
    Modifier | Constructor and Description
    --- | ---
    `` | `RangedPassage(Versification refSystem)` Create an empty RangedPassage.
    `protected` | `RangedPassage(Versification v11n, String refs)`
    `protected` | `RangedPassage(Versification v11n, String refs, Key basis)` Create a Verse from a human readable string.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `add(Key obj)` Add this Verse/VerseRange to this Passage
    `void` | `clear()` Removes all of the elements from this set (optional operation).
    `RangedPassage` | `clone()` This needs to be declared here so that it is visible as a method on a derived Key.
    `boolean` | `contains(Key obj)` Returns true if this collection contains all the specified Verse
    `int` | `countRanges(RestrictionType restrict)` Like countVerses() that counts VerseRanges instead of Verses Returns the number of fragments in this collection.
    `int` | `countVerses()` Returns the number of verses in this collection.
    `boolean` | `isEmpty()` Does this Key have 0 members
    `Iterator<Key>` | `iterator()`
    `(package private) void` | `normalize()` We sometimes need to sort ourselves out ...
    `Iterator<VerseRange>` | `rangeIterator(RestrictionType restrict)` Like iterator() that iterates over VerseRanges instead of Verses.
    `private void` | `readObject(ObjectInputStream in)` Call the support mechanism in AbstractPassage
    `void` | `remove(Key obj)` Remove this Verse/VerseRange from this Passage
    `void` | `retainAll(Key key)` Removes all but the specified element from this set.
    `private void` | `writeObject(ObjectOutputStream out)` Call the support mechanism in AbstractPassage

    - ### Methods inherited from class org.crosswire.jsword.passage.AbstractPassage

      `addAll, addPassageListener, addVerses, blur, booksInPassage, canHaveChildren, compareTo, containsAll, equals, fireContentsChanged, fireIntervalAdded, fireIntervalRemoved, get, getCardinality, getChildCount, getName, getName, getOsisID, getOsisRef, getOverview, getParent, getRangeAt, getRootName, getVerseAt, getVersification, getWhole, hashCode, hasRanges, indexOf, isWhole, lowerEventSuppressionAndTest, lowerNormalizeProtection, optimizeReads, optimizeWrites, raiseEventSuppresion, raiseNormalizeProtection, readDescription, readObjectSupport, removeAll, removePassageListener, reversify, setParent, toString, toVerseRange, trimRanges, trimVerses, writeDescription, writeObjectSupport`

    - ### Methods inherited from class java.lang.Object

      `finalize, getClass, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### serialVersionUID

          private static final long serialVersionUID

      To make serialization work across new versions
      See Also:
        Constant Field Values

    - #### store

          private transient Set<VerseRange> store

      The place the real data is stored

  - ### Constructor Detail

    - #### RangedPassage

          public RangedPassage(Versification refSystem)

      Create an empty RangedPassage. There are no ctors from either Verse or VerseRange so you need to do new `RangedPassage().add(...);`
      Parameters:
        `refSystem` - The Versification to which this Passage belongs.

    - #### RangedPassage

          protected RangedPassage(Versification v11n,
                       String refs,
                       Key basis)
                           throws NoSuchVerseException

      Create a Verse from a human readable string. The opposite of getName(), Given any RangedPassage v1, and the following `RangedPassage v2 = new RangedPassage(v1.getName());` Then `v1.equals(v2);` Theoretically, since there are many ways of representing a RangedPassage as text string comparison along the lines of: `v1.getName().equals(v2.getName())` could be false. However since getName() is standardized this will be true. We don't need to worry about thread safety in a ctor since we don't exist yet.
      Parameters:
        `v11n` - The Versification to which this Passage belongs.
        `refs` - A String containing the text of the RangedPassage
        `basis` - The basis by which to interpret refs
      Throws:
        `NoSuchVerseException` - if refs is invalid

    - #### RangedPassage

          protected RangedPassage(Versification v11n,
                       String refs)
                           throws NoSuchVerseException

      Throws:
        `NoSuchVerseException`

  - ### Method Detail

    - #### clone

          public RangedPassage clone()

      Description copied from interface: `Key`
      This needs to be declared here so that it is visible as a method on a derived Key.
      Specified by:
        `clone` in interface `Key`
      Overrides:
        `clone` in class `AbstractPassage`
      Returns:
        A complete copy of ourselves

    - #### countRanges

          public int countRanges(RestrictionType restrict)

      Description copied from interface: `Passage`
      Like countVerses() that counts VerseRanges instead of Verses Returns the number of fragments in this collection. This does not mean the Passage needs to use VerseRanges, just that it understands the concept.
      Specified by:
        `countRanges` in interface `Passage`
      Overrides:
        `countRanges` in class `AbstractPassage`
      Parameters:
        `restrict` - Do we break ranges at chapter/book boundaries
      Returns:
        the number of VerseRanges in this collection
      See Also:
        `VerseRange`

    - #### countVerses

          public int countVerses()

      Description copied from interface: `Passage`
      Returns the number of verses in this collection. Like Collection.size() This does not mean the Passage needs to use Verses, just that it understands the concept.
      Specified by:
        `countVerses` in interface `Passage`
      Overrides:
        `countVerses` in class `AbstractPassage`
      Returns:
        the number of Verses in this collection
      See Also:
        `Verse`

    - #### iterator

          public Iterator<Key> iterator()

    - #### rangeIterator

          public final Iterator<VerseRange> rangeIterator(RestrictionType restrict)

      Description copied from interface: `Passage`
      Like iterator() that iterates over VerseRanges instead of Verses. Exactly the same data will be traversed, however using rangeIterator() will usually give fewer iterations (and never more)
      Specified by:
        `rangeIterator` in interface `Passage`
      Overrides:
        `rangeIterator` in class `AbstractPassage`
      Parameters:
        `restrict` - Do we break ranges over chapters
      Returns:
        A list enumerator

    - #### isEmpty

          public boolean isEmpty()

      Description copied from interface: `Key`
      Does this Key have 0 members
      Specified by:
        `isEmpty` in interface `Key`
      Overrides:
        `isEmpty` in class `AbstractPassage`
      Returns:
        `true` if this set contains no elements.

    - #### contains

          public boolean contains(Key obj)

      Description copied from interface: `Passage`
      Returns true if this collection contains all the specified Verse
      Specified by:
        `contains` in interface `Key`
      Specified by:
        `contains` in interface `Passage`
      Overrides:
        `contains` in class `AbstractPassage`
      Parameters:
        `obj` - Verse or VerseRange that may exist in this Passage
      Returns:
        true if this collection contains that

    - #### add

          public void add(Key obj)

      Description copied from interface: `Passage`
      Add this Verse/VerseRange to this Passage
      Parameters:
        `obj` - The Verses to be added from this Passage

    - #### clear

          public void clear()

      Description copied from interface: `Key`
      Removes all of the elements from this set (optional operation). This set will be empty after this call returns (unless it throws an exception).
      Specified by:
        `clear` in interface `Key`
      Overrides:
        `clear` in class `AbstractPassage`

    - #### remove

          public void remove(Key obj)

      Description copied from interface: `Passage`
      Remove this Verse/VerseRange from this Passage
      Parameters:
        `obj` - The Verses to be removed from this Passage

    - #### retainAll

          public void retainAll(Key key)

      Description copied from interface: `Key`
      Removes all but the specified element from this set.
      Specified by:
        `retainAll` in interface `Key`
      Overrides:
        `retainAll` in class `AbstractPassage`
      Parameters:
        `key` - object to be left in this set.

    - #### normalize

          final void normalize()

      We sometimes need to sort ourselves out ...

      I don't think we need to be synchronized since we are private and we could check that all public calling of normalize() are synchronized, however this is safe, and I don't think there is a cost associated with a double synchronize. (?)

      Overrides:
        `normalize` in class `AbstractPassage`

    - #### writeObject

          private void writeObject(ObjectOutputStream out)
                            throws IOException

      Call the support mechanism in AbstractPassage
      Parameters:
        `out` - The stream to write our state to
      Throws:
        `IOException` - if the read fails
      See Also:
        `AbstractPassage.writeObjectSupport(ObjectOutputStream)`

    - #### readObject

          private void readObject(ObjectInputStream in)
                           throws IOException,
                                  ClassNotFoundException

      Call the support mechanism in AbstractPassage
      Parameters:
        `in` - The stream to read our state from
      Throws:
        `IOException` - if the read fails
        `ClassNotFoundException` - If the read data is incorrect
      See Also:
        `AbstractPassage.readObjectSupport(ObjectInputStream)`