org.crosswire.jsword.passage
Class Verse

java.lang.Object
  extended by org.crosswire.jsword.passage.Verse
All Implemented Interfaces:
Serializable, Cloneable, Comparable, Key, VerseBase

public final class Verse
extends Object
implements VerseBase, Comparable

A Passage is a pointer to a single verse. Externally its unique identifier is a String of the form "Gen 1:1" Internally we use int[] { book, chapter, verse }

A Verse is designed to be immutable. This is a necessary from a collections point of view. A Verse should always be valid, although some versions may not return any text for verses that they consider to be mis-translated in some way.

Optimization information: I spent some time optimizing this class because it is at the heart of things. My benchmark started st 11.25s. By taking the int[] and turning it into 3 ints and it took 10.8s.
Cacheing the ordinal number just took the time from 12s to 12s! I guess that the time and extra memory taken up by the extra int overrode the time it saved by repeated queries to the same verse. I guess this would change if we were using a [Ranged|Distinct]Passage instead of a Bitwise Passage (as in the test). Maybe it would be a good idea to have an extra class OrdCacheVerse (or something) that gave us the best of both worlds?
Removing the default initialization of the ints took the time down by about 0.25s also.

Distribution Licence:
JSword is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
The License is available on the internet here, or by writing to: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
The copyright to this program is held by it's authors.

Version:
$Id: Verse.java,v 1.33 2004/09/08 19:55:07 dmsmith Exp $
Author:
Joe Walker [joe at eireneh dot com]
See Also:
Licence, Serialized Form

Nested Class Summary
private  class Verse.VerseIterator
          Iterator over 1 verse - For being a VerseBase.
 
Field Summary
private  int book
          The book number.
private static int BOOK
          To make the code more readible, the book is the first part of a int[]
private  int chapter
          The chapter number
private static int CHAPTER
          To make the code more readible, the chapter is the second part of a int[]
static Verse DEFAULT
          The default verse
private static Logger log
          The log stream
private  String originalName
          The original string for picky users
private  Key parent
          The parent key.
(package private) static long serialVersionUID
          To make serialization work across new versions
private  int verse
          The verse number
private static int VERSE
          To make the code more readible, the verse is the third part of a int[]
static String VERSE_OSIS_DELIM
          What characters should we use to separate parts of an OSIS verse reference
static String VERSE_PREF_DELIM1
          What characters should we use to separate the book from the chapter
static String VERSE_PREF_DELIM2
          What characters should we use to separate the chapter from the verse
 
Constructor Summary
Verse()
          The default Verse is Genesis 1:1.
Verse(int ordinal)
          Set a Verse using a Verse Ordinal number - WARNING Do not use this method unless you really know the dangers of doing so.
Verse(int book, int chapter, int verse)
          Create a Verse from book, chapter and verse numbers, throwing up if the specified Verse does not exist.
Verse(int book, int chapter, int verse, boolean patch_up)
          Create a Verse from book, chapter and verse numbers, patching up if the specified verse does not exist.
Verse(String original, int book, int chapter, int verse)
          Create a Verse from book, chapter and verse numbers, throwing up if the specified Verse does not exist.
 
Method Summary
 Verse add(int extra)
          Get the verse that is a few verses on from the one we've got.
 void addAll(Key key)
          Adds the specified element to this set if it is not already present.
 boolean adjacentTo(Verse that)
          Is this verse adjacent to another verse
 void blur(int by, RestrictionType restrict)
          Widen the range of the verses/keys in this list.
 boolean canHaveChildren()
          Returns true if the receiver is a leaf node and can not have children.
 void clear()
          Removes all of the elements from this set (optional operation).
 Object clone()
          Get a copy of ourselves.
 int compareTo(Object obj)
          Compare this to a given object
 boolean contains(Key key)
          Returns true if this set contains the specified element.
 boolean equals(Object obj)
          Is this Object equal to us.
 Key get(int index)
          Gets a key from a specific point in this list.
 int getBook()
          Return the book that we refer to
 int getChapter()
          Return the chapter that we refer to
 int getChildCount()
          Returns the number of elements in this set (its cardinality).
 Verse getFirstVerseInBook()
          Create a new Verse being the first verse in the current book
 Verse getFirstVerseInChapter()
          Create a new Verse being the first verse in the current book
 Verse getLastVerseInBook()
          Create a new Verse being the last verse in the current book
 Verse getLastVerseInChapter()
          Create a new Verse being the last verse in the current book
 String getName()
          Translate the Passage into a human readable string
 String getName(Verse base)
          Translate the Passage into a human readable string
 int getOrdinal()
          Return the verse id that we refer to, where Gen 1:1 = 1, and Rev 22:21 = 31104
 String getOSISName()
          The OSIS defined specification for this Verse.
 Key getParent()
          All keys have parents unless they are the root of a Key.
 int[] getRefArray()
          Return the verse that we refer to
 int getVerse()
          Return the verse that we refer to
 int hashCode()
          This returns the ordinal number of the verse so new Verse("Rev 22:21").hashCode() = 31104.
 int indexOf(Key that)
          Reverse a Key into the position the key holds in the list
 boolean isEmpty()
          Does this Passage have 0 members
 boolean isEndOfBook()
          Is this verse the first in a chapter
 boolean isEndOfChapter()
          Is this verse the first in a chapter
 boolean isSameBook(Verse that)
          Is this verse in the same book as that one
 boolean isSameChapter(Verse that)
          Is this verse in the same chapter as that one
 boolean isStartOfBook()
          Is this verse the first in a chapter
 boolean isStartOfChapter()
          Is this verse the first in a chapter
 Iterator iterator()
           
static Verse max(Verse a, Verse b)
          Return the bigger of the 2 verses.
static Verse min(Verse a, Verse b)
          Return the smaller of the 2 verses.
protected static int parseInt(String text)
          This is simply a convenience function to wrap Integer.parseInt() and give us a reasonable exception on failure.
private  void readObject(ObjectInputStream in)
          Write out the object to the given ObjectOutputStream
 void removeAll(Key key)
          Removes the specified elements from this set if it is present.
 void retainAll(Key key)
          Removes all but the specified element from this set.
private  void set(int ordinal)
          Set the references.
private  void set(int book, int chapter, int verse)
          Verify and set the references.
private  void setAndPatch(int book, int chapter, int verse)
          Mutate into this reference and fix the reference if needed.
 void setParent(Key parent)
          Set a parent Key.
 Verse subtract(int n)
          Get the verse n down from here this Verse.
 int subtract(Verse that)
          How many verses are there in between the 2 Verses.
 String toString()
          Translate the Passage into a human readable string.
 Verse[] toVerseArray()
          Create an array of Verses
 Iterator verseIterator()
          Enumerate over the verse in this verse!.
private  void writeObject(ObjectOutputStream out)
          Write out the object to the given ObjectOutputStream
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

serialVersionUID

static final long serialVersionUID
To make serialization work across new versions

See Also:
Constant Field Values

BOOK

private static final int BOOK
To make the code more readible, the book is the first part of a int[]

See Also:
Constant Field Values

CHAPTER

private static final int CHAPTER
To make the code more readible, the chapter is the second part of a int[]

See Also:
Constant Field Values

VERSE

private static final int VERSE
To make the code more readible, the verse is the third part of a int[]

See Also:
Constant Field Values

VERSE_OSIS_DELIM

public static final String VERSE_OSIS_DELIM
What characters should we use to separate parts of an OSIS verse reference

See Also:
Constant Field Values

VERSE_PREF_DELIM1

public static final String VERSE_PREF_DELIM1
What characters should we use to separate the book from the chapter

See Also:
Constant Field Values

VERSE_PREF_DELIM2

public static final String VERSE_PREF_DELIM2
What characters should we use to separate the chapter from the verse

See Also:
Constant Field Values

DEFAULT

public static final Verse DEFAULT
The default verse


parent

private transient Key parent
The parent key. See the key interface for more information. NOTE(joe): These keys are not serialized, should we?

See Also:
Key

book

private transient int book
The book number. Genesis=1


chapter

private transient int chapter
The chapter number


verse

private transient int verse
The verse number


originalName

private transient String originalName
The original string for picky users


log

private static final Logger log
The log stream

Constructor Detail

Verse

public Verse()
The default Verse is Genesis 1:1. I didn't want to provide this constructor however, you are supposed to provide a default ctor for all beans. For this reason I suggest you don't use it.


Verse

Verse(String original,
      int book,
      int chapter,
      int verse)
throws NoSuchVerseException
Create a Verse from book, chapter and verse numbers, throwing up if the specified Verse does not exist. This constructor is deliberately package protected so that is used only by VerseFactory.

Parameters:
original - The original verse reference
book - The book number (Genesis = 1)
chapter - The chapter number
verse - The verse number
Throws:
NoSuchVerseException - If the reference is illegal

Verse

public Verse(int book,
             int chapter,
             int verse)
      throws NoSuchVerseException
Create a Verse from book, chapter and verse numbers, throwing up if the specified Verse does not exist.

Parameters:
book - The book number (Genesis = 1)
chapter - The chapter number
verse - The verse number
Throws:
NoSuchVerseException - If the reference is illegal

Verse

public Verse(int book,
             int chapter,
             int verse,
             boolean patch_up)
Create a Verse from book, chapter and verse numbers, patching up if the specified verse does not exist.

The actual value of the boolean is ignored. However for future proofing you should only use 'true'. Do not use patch_up=false, use Verse(int, int, int) This so that we can declare this constructor to not throw an exception. Is there a better way of doing this?

Parameters:
book - The book number (Genesis = 1)
chapter - The chapter number
verse - The verse number
patch_up - True to trigger reference fixing

Verse

public Verse(int ordinal)
      throws NoSuchVerseException
Set a Verse using a Verse Ordinal number - WARNING Do not use this method unless you really know the dangers of doing so. Ordinals are not always going to be the same. So you should use a Verse or an int[3] in preference to an int ordinal whenever possible. Ordinal numbers are 1 based and not 0 based.

Parameters:
ordinal - The verse id
Throws:
NoSuchVerseException - If the reference is illegal
Method Detail

toString

public String toString()
Translate the Passage into a human readable string. This is simply an alias for getName();

Overrides:
toString in class Object
Returns:
The string representation

getName

public String getName()
Translate the Passage into a human readable string

Specified by:
getName in interface Key
Specified by:
getName in interface VerseBase
Returns:
The string representation

getName

public String getName(Verse base)
Translate the Passage into a human readable string

Specified by:
getName in interface VerseBase
Parameters:
base - The verse to use to cut down unnecessary output.
Returns:
The string representation

getOSISName

public String getOSISName()
The OSIS defined specification for this Verse. Uses short books names, with "." as a verse part separator.

Specified by:
getOSISName in interface Key
Specified by:
getOSISName in interface VerseBase
Returns:
a String containing the OSIS description of the verses

clone

public Object clone()
             throws CloneNotSupportedException
Get a copy of ourselves. Points to note: Call clone() not new() on member Objects, and on us. Do not use Copy Constructors! - they do not inherit well. Think about this needing to be synchronized If this is not cloneable then writing cloneable children is harder

Overrides:
clone in class Object
Returns:
A complete copy of ourselves
Throws:
CloneNotSupportedException - We don't do this but our kids might

equals

public boolean equals(Object obj)
Is this Object equal to us. Points to note: If you override equals(), you must override hashCode() too. If you are doing this it is a good idea to be immutable.

Overrides:
equals in class Object
Parameters:
obj - The thing to test against
Returns:
True/False is we are or are not equal to obj

hashCode

public int hashCode()
This returns the ordinal number of the verse so new Verse("Rev 22:21").hashCode() = 31104.

However should should not reply on this being true

Overrides:
hashCode in class Object
Returns:
The hashing number

compareTo

public int compareTo(Object obj)
Compare this to a given object

Specified by:
compareTo in interface Comparable
Parameters:
obj - The thing to compare against
Returns:
1 means he is earlier than me, -1 means he is later ...

adjacentTo

public boolean adjacentTo(Verse that)
Is this verse adjacent to another verse

Parameters:
that - The thing to compare against
Returns:
1 means he is earlier than me, -1 means he is later ...

subtract

public int subtract(Verse that)
How many verses are there in between the 2 Verses. The answer is -ve if that is bigger than this. The answer is inclusive of that and exclusive of this, so that gen11.difference(gen12) == 1

Parameters:
that - The Verse to compare this to
Returns:
The count of verses between this and that.

subtract

public Verse subtract(int n)
Get the verse n down from here this Verse.

Parameters:
n - The number to count down by
Returns:
The new Verse

add

public Verse add(int extra)
Get the verse that is a few verses on from the one we've got.

Parameters:
extra - the number of verses later than the one we're one
Returns:
The new verse

getBook

public int getBook()
Return the book that we refer to

Returns:
The book number (Genesis = 1)

getChapter

public int getChapter()
Return the chapter that we refer to

Returns:
The chapter number

getVerse

public int getVerse()
Return the verse that we refer to

Returns:
The verse number

isStartOfChapter

public boolean isStartOfChapter()
Is this verse the first in a chapter

Returns:
true or false ...

isEndOfChapter

public boolean isEndOfChapter()
Is this verse the first in a chapter

Returns:
true or false ...

isStartOfBook

public boolean isStartOfBook()
Is this verse the first in a chapter

Returns:
true or false ...

isEndOfBook

public boolean isEndOfBook()
Is this verse the first in a chapter

Returns:
true or false ...

isSameChapter

public boolean isSameChapter(Verse that)
Is this verse in the same chapter as that one

Parameters:
that - The verse to compate to
Returns:
true or false ...

isSameBook

public boolean isSameBook(Verse that)
Is this verse in the same book as that one

Parameters:
that - The verse to compate to
Returns:
true or false ...

getRefArray

public int[] getRefArray()
Return the verse that we refer to

Returns:
An array of 3 ints 0=book, 1=chapter, 2=verse

getOrdinal

public int getOrdinal()
Return the verse id that we refer to, where Gen 1:1 = 1, and Rev 22:21 = 31104

Returns:
The verse number

max

public static final Verse max(Verse a,
                              Verse b)
Return the bigger of the 2 verses. If the verses are equal() then return Verse a

Parameters:
a - The first verse to compare
b - The second verse to compare
Returns:
The bigger of the 2 verses

min

public static final Verse min(Verse a,
                              Verse b)
Return the smaller of the 2 verses. If the verses are equal() then return Verse a

Parameters:
a - The first verse to compare
b - The second verse to compare
Returns:
The smaller of the 2 verses

toVerseArray

public Verse[] toVerseArray()
Create an array of Verses

Specified by:
toVerseArray in interface VerseBase
Returns:
The array of verses that this makes up
See Also:
VerseBase.verseIterator()

verseIterator

public Iterator verseIterator()
Enumerate over the verse in this verse!. This may seem silly, however is is very useful to be able to treat Verses and Ranges the same (VerseBase) and this is a common accessor.

Specified by:
verseIterator in interface VerseBase
Returns:
A verse iterator
See Also:
VerseBase.verseIterator()

getLastVerseInBook

public Verse getLastVerseInBook()
Create a new Verse being the last verse in the current book

Returns:
The last verse in this book

getLastVerseInChapter

public Verse getLastVerseInChapter()
Create a new Verse being the last verse in the current book

Returns:
The last verse in this book

getFirstVerseInBook

public Verse getFirstVerseInBook()
Create a new Verse being the first verse in the current book

Returns:
The first verse in this book

getFirstVerseInChapter

public Verse getFirstVerseInChapter()
Create a new Verse being the first verse in the current book

Returns:
The first verse in this book

getParent

public Key getParent()
Description copied from interface: Key
All keys have parents unless they are the root of a Key.

Specified by:
getParent in interface Key
Returns:
The parent of this tree, or null if this Key is the root.

setParent

public void setParent(Key parent)
Set a parent Key. This allows us to follow the Key interface more closely, although the concept of a parent for a verse is fairly alien.

Parameters:
parent - The parent Key for this verse

parseInt

protected static int parseInt(String text)
                       throws NoSuchVerseException
This is simply a convenience function to wrap Integer.parseInt() and give us a reasonable exception on failure. It is called by VerseRange hence protected, however I would prefer private

Parameters:
text - The string to be parsed
Returns:
The correctly parsed chapter or verse
Throws:
NoSuchVerseException - If the reference is illegal

setAndPatch

private final void setAndPatch(int book,
                               int chapter,
                               int verse)
Mutate into this reference and fix the reference if needed. This nust only be called from a ctor to maintain immutability

Parameters:
book - The book to set (Genesis = 1)
chapter - The chapter to set
verse - The verse to set

set

private final void set(int book,
                       int chapter,
                       int verse)
                throws NoSuchVerseException
Verify and set the references. This must only be called from a ctor to maintain immutability

Parameters:
book - The book to set (Genesis = 1)
chapter - The chapter to set
verse - The verse to set
Throws:
NoSuchVerseException - If the verse can not be understood

set

private final void set(int ordinal)
                throws NoSuchVerseException
Set the references. This must only be called from a ctor to maintain immutability

Parameters:
ordinal - The ordinal of the verse
Throws:
NoSuchVerseException - If the verse can not be understood

writeObject

private void writeObject(ObjectOutputStream out)
                  throws IOException
Write out the object to the given ObjectOutputStream

Parameters:
out - The stream to write our state to
Throws:
IOException - if the read fails

readObject

private void readObject(ObjectInputStream in)
                 throws IOException,
                        ClassNotFoundException
Write out the object to the given ObjectOutputStream

Parameters:
in - The stream to read our state from
Throws:
IOException - if the read fails
ClassNotFoundException - If the read data is incorrect

canHaveChildren

public boolean canHaveChildren()
Description copied from interface: Key
Returns true if the receiver is a leaf node and can not have children. Any attempt to add()/remove() wlll throw

Specified by:
canHaveChildren in interface Key

getChildCount

public int getChildCount()
Description copied from interface: Key
Returns the number of elements in this set (its cardinality). If this set contains more than Integer.MAX_VALUE elements, returns Integer.MAX_VALUE.

Specified by:
getChildCount in interface Key
Returns:
the number of elements in this set (its cardinality).

isEmpty

public boolean isEmpty()
Description copied from interface: Key
Does this Passage have 0 members

Specified by:
isEmpty in interface Key
Returns:
true if this set contains no elements.

contains

public boolean contains(Key key)
Description copied from interface: Key
Returns true if this set contains the specified element.

Specified by:
contains in interface Key
Parameters:
key - element whose presence in this set is to be tested.
Returns:
true if this set contains the specified element.

iterator

public Iterator iterator()
Specified by:
iterator in interface Key
Returns:
an iterator over the elements in this set.

addAll

public void addAll(Key key)
Description copied from interface: Key
Adds the specified element to this set if it is not already present.

Specified by:
addAll in interface Key
Parameters:
key - element to be added to this set.

removeAll

public void removeAll(Key key)
Description copied from interface: Key
Removes the specified elements from this set if it is present.

Specified by:
removeAll in interface Key
Parameters:
key - object to be removed from this set, if present.

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
Parameters:
key - object to be left in this set.

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

get

public Key get(int index)
Description copied from interface: Key
Gets a key from a specific point in this list.

Specified by:
get in interface Key
Parameters:
index - The index of the Key to retrieve
Returns:
The specified key

indexOf

public int indexOf(Key that)
Description copied from interface: Key
Reverse a Key into the position the key holds in the list

Specified by:
indexOf in interface Key
Parameters:
that - The Key to find
Returns:
The index of the key or -1 if the key is not in the list

blur

public void blur(int by,
                 RestrictionType restrict)
Description copied from interface: Key
Widen the range of the verses/keys in this list. This is primarily for "find x within n verses of y" type applications.

Specified by:
blur in interface Key
Parameters:
by - The number of verses/keys to widen by
restrict - How should we restrict the blurring?
See Also:
Passage

Copyright ? 2003-2004