| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| VerseRangeFactory |
|
| 2.5;2.5 |
| 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 org.crosswire.common.util.StringUtil; | |
| 23 | import org.crosswire.jsword.JSMsg; | |
| 24 | import org.crosswire.jsword.versification.Versification; | |
| 25 | ||
| 26 | /** | |
| 27 | * A factory that creates VerseRanges from user input. | |
| 28 | * | |
| 29 | * @see gnu.lgpl.License The GNU Lesser General Public License for details. | |
| 30 | * @author Joe Walker | |
| 31 | * @author DM Smith | |
| 32 | */ | |
| 33 | public final class VerseRangeFactory { | |
| 34 | ||
| 35 | /** | |
| 36 | * prevent instantiation | |
| 37 | */ | |
| 38 | 0 | private VerseRangeFactory() { |
| 39 | 0 | } |
| 40 | ||
| 41 | /** | |
| 42 | * Construct a VerseRange from a human readable string. For example | |
| 43 | * "Gen 1:1-3" in case the user does not want to have their typing 'fixed' | |
| 44 | * by a meddling patronizing computer. | |
| 45 | * | |
| 46 | * @param v11n | |
| 47 | * The versification for this VerseRange | |
| 48 | * @param orginal | |
| 49 | * The textual representation | |
| 50 | * @return the verse range for the string | |
| 51 | * @exception NoSuchVerseException | |
| 52 | * If the text can not be understood | |
| 53 | */ | |
| 54 | public static VerseRange fromString(Versification v11n, String orginal) throws NoSuchVerseException { | |
| 55 | 0 | return fromString(v11n, orginal, null); |
| 56 | } | |
| 57 | ||
| 58 | /** | |
| 59 | * Construct a VerseRange from a String and a VerseRange. For example given | |
| 60 | * "2:2" and a basis of Gen 1:1-2 the result would be range of 1 verse | |
| 61 | * starting at Gen 2:2. Also given "2:2-5" and a basis of Gen 1:1-2 the | |
| 62 | * result would be a range of 5 verses starting at Gen 1:1. | |
| 63 | * <p> | |
| 64 | * This constructor is different from the (String, Verse) constructor in | |
| 65 | * that if the basis is a range that exactly covers a chapter and the string | |
| 66 | * is a single number, then we assume that the number refers to a chapter | |
| 67 | * and not to a verse. This allows us to have a Passage like "Gen 1,2" and | |
| 68 | * have the 2 understood as chapter 2 and not verse 2 of Gen 1, which would | |
| 69 | * have occurred otherwise. | |
| 70 | * | |
| 71 | * @param v11n | |
| 72 | * The versification for this VerseRange | |
| 73 | * @param original | |
| 74 | * The string describing the verse e.g "2:2" | |
| 75 | * @param basis | |
| 76 | * The verse that forms the basis by which to understand the | |
| 77 | * original. | |
| 78 | * @return the verse range | |
| 79 | * @exception NoSuchVerseException | |
| 80 | * If the reference is illegal | |
| 81 | */ | |
| 82 | public static VerseRange fromString(Versification v11n, String original, VerseRange basis) throws NoSuchVerseException { | |
| 83 | 0 | String[] parts = StringUtil.splitAll(original, VerseRange.RANGE_OSIS_DELIM); |
| 84 | ||
| 85 | 0 | switch (parts.length) { |
| 86 | case 1: | |
| 87 | 0 | return fromText(v11n, original, parts[0], parts[0], basis); |
| 88 | ||
| 89 | case 2: | |
| 90 | 0 | return fromText(v11n, original, parts[0], parts[1], basis); |
| 91 | ||
| 92 | default: | |
| 93 | // TRANSLATOR: The user specified a verse range with too many separators. {0} is a placeholder for the allowable separators. | |
| 94 | 0 | throw new NoSuchVerseException(JSMsg.gettext("A verse range cannot have more than 2 parts. (Parts are separated by {0}) Given {1}", VerseRange.RANGE_OSIS_DELIM, original)); |
| 95 | } | |
| 96 | } | |
| 97 | ||
| 98 | /** | |
| 99 | * The internal mechanism by which we construct a VerseRange | |
| 100 | * | |
| 101 | * @param v11n | |
| 102 | * The versification for this VerseRange | |
| 103 | * @param original | |
| 104 | * The string describing the verse e.g "2:2" | |
| 105 | * @param startVerseDesc | |
| 106 | * The part of the range before the range separator | |
| 107 | * @param endVerseDesc | |
| 108 | * The part of the range after the range separator | |
| 109 | * @param basis | |
| 110 | * The verse that forms the basis by which to understand the | |
| 111 | * original. | |
| 112 | * @exception NoSuchVerseException | |
| 113 | * If the reference is illegal | |
| 114 | */ | |
| 115 | private static VerseRange fromText(Versification v11n, String original, String startVerseDesc, String endVerseDesc, VerseRange basis) throws NoSuchVerseException { | |
| 116 | 0 | String[] startParts = AccuracyType.tokenize(startVerseDesc); |
| 117 | 0 | AccuracyType accuracyStart = AccuracyType.fromText(v11n, original, startParts, basis); |
| 118 | 0 | Verse start = accuracyStart.createStartVerse(v11n, basis, startParts); |
| 119 | 0 | v11n.validate(start.getBook(), start.getChapter(), start.getVerse()); |
| 120 | ||
| 121 | String[] endParts; | |
| 122 | 0 | if (startVerseDesc.equals(endVerseDesc)) { |
| 123 | 0 | endParts = startParts; |
| 124 | } else { | |
| 125 | 0 | endParts = AccuracyType.tokenize(endVerseDesc); |
| 126 | } | |
| 127 | ||
| 128 | 0 | AccuracyType accuracyEnd = AccuracyType.fromText(v11n, original, endParts, accuracyStart, basis); |
| 129 | 0 | Verse end = accuracyEnd.createEndVerse(v11n, start, endParts); |
| 130 | 0 | v11n.validate(end.getBook(), end.getChapter(), end.getVerse()); |
| 131 | ||
| 132 | 0 | return new VerseRange(v11n, start, end); |
| 133 | } | |
| 134 | } |