public RangedPassage convert(RangedPassage rangedPassage, Versification toVersification) { RangedPassage result = new RangedPassage(toVersification); Iterator<VerseRange> iter = rangedPassage.rangeIterator(RestrictionType.NONE); while (iter.hasNext()) { result.add(convert(iter.next(), toVersification)); } return result; }
/** * Create a Verse from a human readable string. The opposite of getName(), * Given any RangedPassage v1, and the following * <code>RangedPassage v2 = new RangedPassage(v1.getName());</code> Then * <code>v1.equals(v2);</code> Theoretically, since there are many ways of * representing a RangedPassage as text string comparison along the lines * of: <code>v1.getName().equals(v2.getName())</code> 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. * * @param v11n * The Versification to which this Passage belongs. * @param refs * A String containing the text of the RangedPassage * @param basis * The basis by which to interpret refs * @throws NoSuchVerseException * if refs is invalid */ protected RangedPassage(Versification v11n, String refs, Key basis) throws NoSuchVerseException { super(v11n, refs); store = new TreeSet<VerseRange>(); addVerses(refs, basis); normalize(); }
@Override public boolean containsAll(Passage that) { if (ranged != null) { return ranged.containsAll(that); } return super.containsAll(that); }
@Override public void clear() { optimizeWrites(); store.clear(); fireIntervalRemoved(this, null, null); }
public void add(Key obj) { optimizeWrites(); VerseRange thatRange = toVerseRange(getVersification(), obj); store.add(thatRange); normalize(); // we do an extra check here because the cost of calculating the // params is non-zero an may be wasted if (suppressEvents == 0) { fireIntervalAdded(this, thatRange.getStart(), thatRange.getEnd()); } }
public void remove(Key obj) { optimizeWrites(); VerseRange thatRange = toVerseRange(getVersification(), obj); boolean removed = false; // This allows us to modify store which iterating through a copy Set<Key> newStore = new TreeSet<Key>(); newStore.addAll(store); // go through all the VerseRanges for (Key aKey : newStore) { // if this range touches the range to be removed ... VerseRange thisRange = (VerseRange) aKey; if (thisRange.overlaps(thatRange)) { // ... remove it and add the remainder store.remove(thisRange); VerseRange[] vra = VerseRange.remainder(thisRange, thatRange); for (int i = 0; i < vra.length; i++) { store.add(vra[i]); } removed = true; } } if (removed) { normalize(); } // we do an extra check here because the cost of calculating the // params is non-zero an may be wasted if (suppressEvents == 0) { fireIntervalRemoved(this, thatRange.getStart(), thatRange.getEnd()); } }
@Override public void optimizeReads() { raiseEventSuppresion(); // We have to create the cached versions of these separately // so that the calculations made by addAll(this) can // safely call methods like countVerses() without any // danger of them being optimized before the optimizations // are ready for use. DistinctPassage dtemp = new DistinctPassage(getVersification()); dtemp.raiseEventSuppresion(); dtemp.addAll(this); dtemp.lowerEventSuppressionAndTest(); RangedPassage rtemp = new RangedPassage(getVersification()); rtemp.raiseEventSuppresion(); rtemp.addAll(this); rtemp.lowerEventSuppressionAndTest(); distinct = dtemp; ranged = rtemp; // This is just an optimization so we dont need to fire any events lowerEventSuppressionAndTest(); }
@Override public Passage createEmptyPassage(Versification v11n) { return new RangedPassage(v11n); } },
@Override public boolean contains(Key obj) { // Even for the contains(VerseRange) case, the simple // 'return store.contains(that);' will not work because // VerseRanges can contain others but not be equal to them. VerseRange thatRange = toVerseRange(getVersification(), obj); Iterator<VerseRange> it = rangeIterator(RestrictionType.NONE); while (it.hasNext()) { VerseRange thisRange = it.next(); if (thisRange.contains(thatRange)) { return true; } } // If it is not a Verse or a VerseRange then it's not here, // this also copes with the searches failing. return false; }
@Override public Iterator<VerseRange> rangeIterator(RestrictionType restrict) { if (ranged != null) { return ranged.rangeIterator(restrict); } return super.rangeIterator(restrict); }
public Iterator<Key> iterator() { return new VerseIterator(getVersification(), rangeIterator(RestrictionType.NONE)); }
@Override public int countRanges(RestrictionType restrict) { if (ranged != null) { return ranged.countRanges(restrict); } return super.countRanges(restrict); }
@Override public VerseRange getRangeAt(int offset, RestrictionType restrict) throws ArrayIndexOutOfBoundsException { if (ranged != null) { return ranged.getRangeAt(offset, restrict); } return super.getRangeAt(offset, restrict); }
@Override public void retainAll(Key key) { optimizeWrites(); Iterator<VerseRange> thatIter = ((RangedPassage) key).rangeIterator(RestrictionType.CHAPTER); while (thatIter.hasNext()) { VerseRange thatRange = thatIter.next(); Iterator<VerseRange> thisIter = rangeIterator(RestrictionType.NONE); while (thisIter.hasNext()) { Iterator<Key> thatIter = key.iterator(); while (thatIter.hasNext()) { VerseRange thatRange = toVerseRange(getVersification(), thatIter.next()); Iterator<VerseRange> thisIter = rangeIterator(RestrictionType.NONE); while (thisIter.hasNext()) { normalize(); fireIntervalRemoved(this, null, null);
/** Simplify creation of an empty passage object of the default type, with the required v11n. * * @param versification required v11n for new Passage * @return empty Passage */ private Passage createEmptyPassage(Versification versification) { return new RangedPassage(versification); }
@Override public int countVerses() { Iterator<VerseRange> it = rangeIterator(RestrictionType.NONE); int count = 0; while (it.hasNext()) { VerseRange range = it.next(); count += range.getCardinality(); } return count; }
@Override public Passage createPassage(Versification v11n, String passage, Key basis) throws NoSuchVerseException { if (passage == null || passage.length() == 0) { return createEmptyPassage(v11n); } return new RangedPassage(v11n, passage, basis); }
Set<VerseRange> newStore = new TreeSet<VerseRange>(); Iterator<VerseRange> it = rangeIterator(RestrictionType.NONE); while (it.hasNext()) { next = it.next();
/** * Maps a whole passage, and does so verse by verse. We can't do any better, since, we may for * example have: * Ps.1.1-Ps.1.10 => Ps.1.2-Ps.1.11 so one would think we can simply map each of the start and end verses. * However, this would be inaccurate since verse 9 might map to verse 12, 13, etc. * * @param key the key if the source versification * @param target the target versification * @return the new key in the new versification */ public Passage map(final Passage key, final Versification target) { if (key.getVersification().equals(target)) { return key; } Passage newPassage = new RangedPassage(target); Iterator<Key> verses = key.iterator(); while (verses.hasNext()) { Verse verse = (Verse) verses.next(); newPassage.addAll(this.mapVerse(verse, target)); } return newPassage; }
public boolean containsAll(Passage that) { if (that instanceof RangedPassage) { Iterator<VerseRange> iter = null; iter = ((RangedPassage) that).rangeIterator(RestrictionType.NONE); while (iter.hasNext()) { if (!contains(iter.next())) { return false; } } } else { Iterator<Key> iter = that.iterator(); while (iter.hasNext()) { if (!contains(iter.next())) { return false; } } } return true; }