Coverage Report - org.crosswire.jsword.passage.Passage
 
Classes in this File Line Coverage Branch Coverage Complexity
Passage
N/A
N/A
1
 
 1  
 /**
 2  
  * Distribution License:
 3  
  * JSword is free software; you can redistribute it and/or modify it under
 4  
  * the terms of the GNU Lesser General Public License, version 2.1 or later
 5  
  * as published by the Free Software Foundation. This program is distributed
 6  
  * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 7  
  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 8  
  * See the GNU Lesser General Public License for more details.
 9  
  *
 10  
  * The License is available on the internet at:
 11  
  *      http://www.gnu.org/copyleft/lgpl.html
 12  
  * or by writing to:
 13  
  *      Free Software Foundation, Inc.
 14  
  *      59 Temple Place - Suite 330
 15  
  *      Boston, MA 02111-1307, USA
 16  
  *
 17  
  * © CrossWire Bible Society, 2005 - 2016
 18  
  *
 19  
  */
 20  
 package org.crosswire.jsword.passage;
 21  
 
 22  
 import java.io.IOException;
 23  
 import java.io.Reader;
 24  
 import java.io.Writer;
 25  
 import java.util.Iterator;
 26  
 
 27  
 /**
 28  
  * A Passage is a specialized Collection of Verses. The additions are:
 29  
  * <ul>
 30  
  * <li>List blurring
 31  
  * <li>Range Counting and iteration (in addition to Verse counting etc)
 32  
  * <li>List change notification, so you can register to update yourself, and
 33  
  * this goes hand in hand with a added thread-safe contract.
 34  
  * <li>getName() to be more VerseBase like.
 35  
  * <li>Human readable serialization. So we can read and write to and from OLB
 36  
  * style Passage files.
 37  
  * </ul>
 38  
  * 
 39  
  * <p>
 40  
  * Passage no longer extends the Collection interface to avoid J2SE 1.1/1.2
 41  
  * portability problems, and because many of the things that a Passage does rely
 42  
  * on consecutive Verses which are an alien concept to Collections. So users
 43  
  * would have to use the Passage interface anyway.
 44  
  * 
 45  
  * <p>
 46  
  * Other arguments for and against.
 47  
  * <ul>
 48  
  * <li>The generic version will postpone some type errors to runtime. Is this a
 49  
  * huge problem? Are there many syntax errors that would be lost? Probably not.
 50  
  * <li>The specific version would stop enhancements like add("Gen 1:1"); (But
 51  
  * this is just syntactical sugar anyway).
 52  
  * <li>The specific version allows functionality by is-a as well as has-a. But a
 53  
  * Passage is fundamentally different so this is not that much use.
 54  
  * <li>At the end of the day I expect people to use getName() instead of
 55  
  * toString() and blur(), both of which are Passage things not Collection
 56  
  * things. So the general use of these classes is via a Passage interface not a
 57  
  * Collections one.
 58  
  * <li>Note that the implementations of Passage could not adhere strictly to the
 59  
  * Collections interface in returning false from add(), remove() etc, to specify
 60  
  * if the Collection was changed. Given ranges and the like this can get very
 61  
  * time consuming and complex.
 62  
  * </ul>
 63  
  * 
 64  
  * <p>
 65  
  * The upshot of all this is that I am removing the Collections interface from
 66  
  * Passage.
 67  
  * 
 68  
  * <p>
 69  
  * I considered giving Passages names to allow for a CLI that could use named
 70  
  * RangedPassages, however that is perhaps better left to another class.
 71  
  * 
 72  
  * @see gnu.lgpl.License The GNU Lesser General Public License for details.
 73  
  * @author Joe Walker
 74  
  */
 75  
 public interface Passage extends VerseKey<Passage> {
 76  
     /**
 77  
      * A summary of the verses in this Passage For example
 78  
      * "10 verses in 4 books"
 79  
      * 
 80  
      * @return a String containing an overview of the verses
 81  
      */
 82  
     String getOverview();
 83  
 
 84  
     /**
 85  
      * Returns the number of verses in this collection. Like Collection.size()
 86  
      * This does not mean the Passage needs to use Verses, just that it
 87  
      * understands the concept.
 88  
      * 
 89  
      * @return the number of Verses in this collection
 90  
      * @see Verse
 91  
      */
 92  
     int countVerses();
 93  
 
 94  
     /**
 95  
      * Determine whether there are two or more ranges.
 96  
      * 
 97  
      * @param restrict
 98  
      *            Do we break ranges at chapter/book boundaries
 99  
      * @return whether there are two or more ranges
 100  
      * @see VerseRange
 101  
      */
 102  
     boolean hasRanges(RestrictionType restrict);
 103  
 
 104  
     /**
 105  
      * Like countVerses() that counts VerseRanges instead of Verses Returns the
 106  
      * number of fragments in this collection. This does not mean the Passage
 107  
      * needs to use VerseRanges, just that it understands the concept.
 108  
      * 
 109  
      * @param restrict
 110  
      *            Do we break ranges at chapter/book boundaries
 111  
      * @return the number of VerseRanges in this collection
 112  
      * @see VerseRange
 113  
      */
 114  
     int countRanges(RestrictionType restrict);
 115  
 
 116  
     /**
 117  
      * Ensures that there are a maximum of <code>count</code> Verses in this
 118  
      * Passage. If there were more than <code>count</code> Verses then a new
 119  
      * Passage is created containing the Verses from <code>count</code>+1
 120  
      * onwards. If there was not greater than <code>count</code> in the Passage,
 121  
      * then the passage remains unchanged, and null is returned.
 122  
      * 
 123  
      * @param count
 124  
      *            The maximum number of Verses to allow in this collection
 125  
      * @return A new Passage containing the remaining verses or null
 126  
      * @see Verse
 127  
      */
 128  
     Passage trimVerses(int count);
 129  
 
 130  
     /**
 131  
      * Ensures that there are a maximum of <code>count</code> VerseRanges in
 132  
      * this Passage. If there were more than <code>count</code> VerseRanges then
 133  
      * a new Passage is created containing the VerseRanges from
 134  
      * <code>count</code>+1 onwards. If there was not greater than
 135  
      * <code>count</code> in the Passage, then the passage remains unchanged,
 136  
      * and null is returned.
 137  
      * 
 138  
      * @param count
 139  
      *            The maximum number of VerseRanges to allow in this collection
 140  
      * @param restrict
 141  
      *            Do we break ranges at chapter/book boundaries
 142  
      * @return A new Passage containing the remaining verses or null
 143  
      * @see VerseRange
 144  
      */
 145  
     Passage trimRanges(int count, RestrictionType restrict);
 146  
 
 147  
     /**
 148  
      * How many books are there in this Passage
 149  
      * 
 150  
      * @return The number of distinct books
 151  
      */
 152  
     int booksInPassage();
 153  
 
 154  
     /**
 155  
      * Get a specific Verse from this collection
 156  
      * 
 157  
      * @param offset
 158  
      *            The verse offset (legal values are 0 to countVerses()-1)
 159  
      * @return The Verse
 160  
      * @throws ArrayIndexOutOfBoundsException
 161  
      *             If the offset is out of range
 162  
      */
 163  
     Verse getVerseAt(int offset) throws ArrayIndexOutOfBoundsException;
 164  
 
 165  
     /**
 166  
      * Get a specific VerseRange from this collection
 167  
      * 
 168  
      * @param offset
 169  
      *            The verse range offset (legal values are 0 to countRanges()-1)
 170  
      * @param restrict
 171  
      *            Do we break ranges at chapter/book boundaries
 172  
      * @return The Verse Range
 173  
      * @throws ArrayIndexOutOfBoundsException
 174  
      *             If the offset is out of range
 175  
      */
 176  
     VerseRange getRangeAt(int offset, RestrictionType restrict) throws ArrayIndexOutOfBoundsException;
 177  
 
 178  
     /**
 179  
      * Like iterator() that iterates over VerseRanges instead of Verses.
 180  
      * Exactly the same data will be traversed, however using rangeIterator()
 181  
      * will usually give fewer iterations (and never more)
 182  
      * 
 183  
      * @param restrict
 184  
      *            Do we break ranges over chapters
 185  
      * @return A list enumerator
 186  
      */
 187  
     Iterator<VerseRange> rangeIterator(RestrictionType restrict);
 188  
 
 189  
     /**
 190  
      * Returns true if this collection contains all the specified Verse
 191  
      * 
 192  
      * @param that
 193  
      *            Verse or VerseRange that may exist in this Passage
 194  
      * @return true if this collection contains that
 195  
      */
 196  
     boolean contains(Key that);
 197  
 
 198  
     /**
 199  
      * Add this Verse/VerseRange to this Passage
 200  
      * 
 201  
      * @param that
 202  
      *            The Verses to be added from this Passage
 203  
      */
 204  
     void add(Key that);
 205  
 
 206  
     /**
 207  
      * Remove this Verse/VerseRange from this Passage
 208  
      * 
 209  
      * @param that
 210  
      *            The Verses to be removed from this Passage
 211  
      */
 212  
     void remove(Key that);
 213  
 
 214  
     /**
 215  
      * Returns true if this Passage contains all of the verses in that Passage
 216  
      * 
 217  
      * @param that
 218  
      *            Passage to be checked for containment in this collection.
 219  
      * @return true if this reference contains all of the Verses in that Passage
 220  
      */
 221  
     boolean containsAll(Passage that);
 222  
 
 223  
     /**
 224  
      * To be compatible with humans we read/write ourselves to a file that a
 225  
      * human can read and even edit. OLB verse.lst integration is a good goal
 226  
      * here.
 227  
      * 
 228  
      * @param in
 229  
      *            The stream to read from
 230  
      * @exception java.io.IOException
 231  
      *                If the file/network etc breaks
 232  
      * @exception NoSuchVerseException
 233  
      *                If the file was invalid
 234  
      */
 235  
     void readDescription(Reader in) throws IOException, NoSuchVerseException;
 236  
 
 237  
     /**
 238  
      * To be compatible with humans we read/write ourselves to a file that a
 239  
      * human can read and even edit. OLB verse.lst integration is a good goal
 240  
      * here.
 241  
      * 
 242  
      * @param out
 243  
      *            The stream to write to
 244  
      * @exception java.io.IOException
 245  
      *                If the file/network etc breaks
 246  
      */
 247  
     void writeDescription(Writer out) throws IOException;
 248  
 
 249  
     /**
 250  
      * For performance reasons we may well want to hint to the Passage that we
 251  
      * have done editing it for now and that it is safe to cache certain values
 252  
      * to speed up future reads. Any action taken by this method will be undone
 253  
      * simply by making a future edit, and the only loss in calling
 254  
      * optimizeReads() is a loss of time if you then persist in writing to the
 255  
      * Passage.
 256  
      */
 257  
     void optimizeReads();
 258  
 
 259  
     /**
 260  
      * Event Listeners - Add Listener
 261  
      * 
 262  
      * @param li
 263  
      *            The listener to add
 264  
      */
 265  
     void addPassageListener(PassageListener li);
 266  
 
 267  
     /**
 268  
      * Event Listeners - Remove Listener
 269  
      * 
 270  
      * @param li
 271  
      *            The listener to remove
 272  
      */
 273  
     void removePassageListener(PassageListener li);
 274  
 }