/******************************************************************************* * Copyright (c) 2012, Directors of the Tyndale STEP Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * Neither the name of the Tyndale House, Cambridge (www.TyndaleHouse.com) * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ package com.tyndalehouse.step.core.models.stats; import com.tyndalehouse.step.core.models.KeyWrapper; import com.tyndalehouse.step.core.utils.StringUtils; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * @author chrisburrell */ public class PassageStat { private Map<String, Integer> stats = new HashMap<String, Integer>(128); private KeyWrapper reference; /** * Adds the word to the current stats * * @param word the word */ public void addWord(final String word) { Integer counts = this.stats.get(word); if (counts == null) { counts = 0; } this.stats.put(word, counts + 1); } /** * Tries various cases before adding a word * @param word the root word that we want to add */ public void addWordTryCases(final String word) { String key = word; Integer counts = this.stats.get(word); if(counts == null) { //try upper case key = word.toUpperCase(); counts = this.stats.get(key); if(counts == null) { //try lower case key = word.toLowerCase(); counts = this.stats.get(key); if(counts == null) { //try all title case key = StringUtils.toTitleCase(word, true); counts = this.stats.get(key); if(counts == null) { key = StringUtils.toTitleCase(word, false); counts = this.stats.get(key); } } } } if(counts == null) { //didn't find it anywhere in the list, so if the word is all upper case, we'll favour the title case version counts = 0; } //key ends up being one of the chain of ifs above in priority order. this.stats.put(key, counts + 1); } /** * Trims from the bottom up, leaving the more frequent words there until we have < maxWords */ public void trim(final int maxWords) { trimWords(maxWords, 1); } /** * @param maxWords the number of words to keep * @param trimOutOccurrences the number for which we won't keep */ private void trimWords(final int maxWords, final int trimOutOccurrences) { if(this.stats.size() < maxWords) { return; } final Iterator<Map.Entry<String, Integer>> iterator = this.stats.entrySet().iterator(); while (iterator.hasNext()) { final Map.Entry<String, Integer> next = iterator.next(); if (next.getValue() == trimOutOccurrences) { iterator.remove(); } } trimWords(maxWords, trimOutOccurrences+1); } /** * @return the stats */ public Map<String, Integer> getStats() { return this.stats; } /** * @param stats the new stats */ public void setStats(final Map<String, Integer> stats) { this.stats = stats; } /** * @return the reference for this particular stat */ public KeyWrapper getReference() { return reference; } /** * @param reference the reference for this particular stat */ public void setReference(final KeyWrapper reference) { this.reference = reference; } }