[jsword-svn] jsword/java/limbo/org/crosswire/jsword/book s

jswordcvs at crosswire.org jswordcvs at crosswire.org
Fri Apr 1 10:09:48 MST 2005


Update of /cvs/jsword/jsword/java/limbo/org/crosswire/jsword/book
In directory www.crosswire.org:/tmp/cvs-serv5088/java/limbo/org/crosswire/jsword/book

Added Files:
	Translation.java Strongs.java StudyTool.java Openness.java 
Log Message:
Improved ranking, bible display and fixed a few bugs.

--- NEW FILE: Openness.java ---

package org.crosswire.jsword.book;

import java.io.Serializable;

import org.crosswire.common.util.MsgBase;

/**
 * A definition of how open a Bible is. Can is be freely copied or is
 * it proprietary.
 * 
 * <p><table border='1' cellPadding='3' cellSpacing='0'>
 * <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
 *
 * Distribution Licence:<br />
 * 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.<br />
 * 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.<br />
 * The License is available on the internet
 * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA<br />
 * The copyright to this program is held by it's authors.
 * </font></td></tr></table>
 * @see gnu.gpl.Licence
 * @author Joe Walker [joe at eireneh dot com]
 * @version $Id: Openness.java,v 1.1 2005/04/01 17:09:46 dmsmith Exp $
 */
public class Openness implements Serializable
{
    /**
     * If the data of unknown distribution status
     */
    public static final Openness UNKNOWN = new Openness(Msg.OPEN_UNKNOWN);

    /**
     * If the data free of copyright restrictions
     */
    public static final Openness PD = new Openness(Msg.OPEN_PD);

    /**
     * Does the data have a licence that permits free use
     */
    public static final Openness FREE = new Openness(Msg.OPEN_FREE);

    /**
     * Is the data freely redistributable
     */
    public static final Openness COPYABLE = new Openness(Msg.OPEN_COPYABLE);

    /**
     * Is the data sold for commercial profit
     */
    public static final Openness COMMERCIAL = new Openness(Msg.OPEN_COMMERCIAL);

    /**
     * Prevent anyone else from doing this
     */
    private Openness(MsgBase msg)
    {
        name = msg.toString();
    }

    /**
     * Lookup method to convert from a String
     */
    public static Openness fromString(String name)
    {
        for (int i = 0; i < VALUES.length; i++)
        {
            Openness o = VALUES[i];
            if (o.name.equalsIgnoreCase(name))
            {
                return o;
            }
        }
        // cannot get here
        assert false;
        return null;
    }

    /**
     * Lookup method to convert from an integer
     */
    public static Openness fromInteger(int i)
    {
        return VALUES[i];
    }

    /**
     * Prevent subclasses from overriding canonical identity based Object methods
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public final boolean equals(Object o)
    {
        return super.equals(o);
    }

    /**
     * Prevent subclasses from overriding canonical identity based Object methods
     * @see java.lang.Object#hashCode()
     */
    public final int hashCode()
    {
        return super.hashCode();
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    public String toString()
    {
        return name;
    }

    /**
     * The name of the Openness
     */
    private String name;

    // Support for serialization
    private static int nextObj;
    private final int obj = nextObj++;

    Object readResolve()
    {
        return VALUES[obj];
    }

    private static final Openness[] VALUES =
    {
        UNKNOWN,
        PD,
        FREE,
        COPYABLE,
        COMMERCIAL
    };

    /**
     * Serialization ID
     */
    private static final long serialVersionUID = 3257844364125483320L;
}

--- NEW FILE: Translation.java ---
package org.crosswire.jsword.book;

import org.crosswire.jsword.passage.Key;

/**
 * A Translation links a Greek/Hebrew work with a localized translation, and can
 * link a number of verses that are examples of the given translation.
 * 
 * <p>Perhpas we should consider linking to the Bible that translated the
 * original in the ways listed in the Key?.</p>
 * 
 * <p><table border='1' cellPadding='3' cellSpacing='0'>
 * <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
 *
 * Distribution Licence:<br />
 * 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.<br />
 * 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.<br />
 * The License is available on the internet
 * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA<br />
 * The copyright to this program is held by it's authors.
 * </font></td></tr></table>
 * @see gnu.gpl.Licence
 * @author Joe Walker [joe at eireneh dot com]
 * @version $Id: Translation.java,v 1.1 2005/04/01 17:09:46 dmsmith Exp $
 */
public class Translation
{
    /**
     * All translations must be from a greek/hebrew word, to a localized word
     * @param word The localized word(s).
     * @param strongs The original word.
     */
    public Translation(String word, Strongs strongs, Key key)
    {
        this.word = word;
        this.strongs = strongs;
        this.key = key;
    }

    /**
     * Accessor for the localized translation
     */
    public String getWord()
    {
        return word;
    }

    /**
     * Accessor for the original word.
     */
    public Strongs getStrongs()
    {
        return strongs;
    }

    /**
     * Accessor for the Keys that translate the word/number in this way.
     */
    public Key getKey()
    {
        return key;
    }

    /**
     * The localized word
     */
    private String word;

    /**
     * The original Strongs number
     */
    private Strongs strongs;

    /**
     * The matching verses
     */
    private Key key;
}

--- NEW FILE: Strongs.java ---
package org.crosswire.jsword.book;

import org.jdom.Element;

/**
 * Strongs is a convenience way of recording a Strongs number instead of
 * using a String with a number in it.
 * 
 * <p>A Strongs number can not be a number because Hebrew and Greek numbers are
 * distinguished only by the Hebrew having a 0 at the start.
 * <p>The class is immutable.
 * <p>Numbers that exist:<ul>
 * <li>Hebrew: 1-8674
 * <li>Greek: 1-5624 (but not 1418, 2717, 3203-3302, 4452)
 * <li>Parsing: 0, 5625-5773, 8675-8809 (but not 5626, 5653, 5687, 5767, 8679)
 * </ul>
 * 
 * <p><table border='1' cellPadding='3' cellSpacing='0'>
 * <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
 *
 * Distribution Licence:<br />
 * 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.<br />
 * 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.<br />
 * The License is available on the internet
 * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA<br />
 * The copyright to this program is held by it's authors.
 * </font></td></tr></table>
 * @see gnu.gpl.Licence
 * @author Joe Walker [joe at eireneh dot com]
 * @version $Id: Strongs.java,v 1.1 2005/04/01 17:09:46 dmsmith Exp $
 */
public class Strongs
{
    /**
     * Create a Strongs number from an OLB descriptive string.
     * @param desc The OLB style descriptive string
     */
    public Strongs(String desc) throws BookException
    {
        // This is only the local copy.
        desc = desc.trim();

        try
        {
            if (desc.charAt(0) == '<')
            {
                // It's a Greek or Hebrew number
                if (desc.charAt(desc.length() - 1) != '>')
                {
                    throw new BookException(Msg.STRONGS_ERROR_PARSE, new Object[] { desc });
                }

                if (desc.charAt(1) == '0')
                {
                    set(HEBREW, Integer.parseInt(desc.substring(2, desc.length() - 1)));
                }
                else
                {
                    set(GREEK, Integer.parseInt(desc.substring(1, desc.length() - 1)));
                }
            }
            else if (desc.charAt(0) == '(')
            {
                // It's a parsing number
                if (desc.charAt(desc.length() - 1) != ')')
                {
                    throw new BookException(Msg.STRONGS_ERROR_PARSE, new Object[] { desc });
                }

                set(PARSING, Integer.parseInt(desc.substring(1, desc.length() - 1)));
            }

            throw new BookException(Msg.STRONGS_ERROR_PARSE, new Object[] { desc });
        }
        catch (NumberFormatException ex)
        {
            throw new BookException(Msg.STRONGS_ERROR_NUMBER, new Object[] { desc });
        }
    }

    /**
     * Create a Strongs number from a type and a number
     * @param type 0=HEBREW, 1=GREEK, 2=PARSING
     * @param number The strongs number
     */
    public Strongs(int type, int number) throws BookException
    {
        set(type, number);
    }

    /**
     * Work out what the Strongs number is from the W element
     * @param w The element to investigate
     */
    public Strongs(Element w) throws BookException
    {
        String lemma = w.getAttributeValue(OSISUtil.ATTRIBUTE_W_LEMMA);

        // LATER(joe): I think it goes x-study:[H|G]number, but this will need fixing...
        int colonpos = lemma.indexOf(":"); //$NON-NLS-1$
        if (colonpos != -1)
        {
            lemma = lemma.substring(colonpos + 1);
        }

        int newtype = -1;
        if (lemma.charAt(0) == 'H')
        {
            newtype = HEBREW;
            lemma = lemma.substring(1);
        }
        else if (lemma.charAt(0) == 'G')
        {
            newtype = GREEK;
            lemma = lemma.substring(1);
        }
        else
        {
            newtype = PARSING;
        }

        int newnum = Integer.parseInt(lemma);

        set(newtype, newnum);
    }

    /**
     * The string that would be used by the On-Line Bible to describe this
     * number
     * @return The OLB sytle string
     */
    public String getOLBName()
    {
        switch (type)
        {
        case GREEK:
            return "<" + number + '>'; //$NON-NLS-1$
        case HEBREW:
            return "<0" + number + '>'; //$NON-NLS-1$
        case PARSING:
            return "(" + number + ')'; //$NON-NLS-1$
        default:
            assert false : type;
            return "!Error!"; //$NON-NLS-1$
        }
    }

    /**
     * A very short description of the Strongs number
     * @return The short description
     */
    public String getDescription()
    {
        switch (type)
        {
        case GREEK:
            return Msg.STRONGS_GREEK.toString() + number;
        case HEBREW:
            return Msg.STRONGS_HEBREW.toString() + number;
        case PARSING:
            return Msg.STRONGS_PARSING.toString() + number;
        default:
            assert false : type;
            return "!Error!"; //$NON-NLS-1$
        }
    }

    /**
     * Default to returning the OLB name for this number
     * @return A descriptive String
     */
    public String toString()
    {
        return getOLBName();
    }

    /**
     * @return The type of this Strongs number
     */
    public int getType()
    {
        return type;
    }

    /**
     * @return The actual number that this represents
     */
    public int getNumber()
    {
        return 0;
    }

    /**
     * Is this number a Greek one?
     * @return true if the number is Greek
     */
    public boolean isGreek()
    {
        return type == GREEK;
    }

    /**
     * Is this number a Hebrew one?
     * @return true if the number is Hebrew
     */
    public boolean isHebrew()
    {
        return type == HEBREW;
    }

    /**
     * Is this number a Parsing one?
     * @return true if the number is Parsing
     */
    public boolean isParsing()
    {
        return type == PARSING;
    }

    /**
     * Create a Strongs number from a type and a number.
     * This is private since it should only be called from a constructor
     * to keep this class immutable.
     * @param type 0=HEBREW, 1=GREEK, 2=PARSING
     * @param number The strongs number
     */
    private void set(int type, int number) throws BookException
    {
        this.type = type;
        this.number = number;

        // Check validity
        switch (type)
        {
        case HEBREW:
            if (number > HEBREW_MAX || number < 1)
            {
                throw new BookException(Msg.STRONGS_ERROR_HEBREW, new Object[] { new Integer(HEBREW_MAX), new Integer(number) });
            }
            break;

        case GREEK:
            if (number > GREEK_MAX || number < 1)
            {
                throw new BookException(Msg.STRONGS_ERROR_GREEK, new Object[] { new Integer(GREEK_MAX), new Integer(number) });
            }
            // We have not checked for 1418, 2717, 3203-3302, 4452 which do not appear to
            // but legal numbers for Greek words. Should we do this?
            break;

        case PARSING:
            if (number < 1)
            {
                throw new BookException(Msg.STRONGS_ERROR_PARSING, new Object[] { new Integer(number) });
            }
            // The correct range seems to be: 0, 5625-5773, 8675-8809, but not 5626, 5653, 5687, 5767, 8679
            // I'm not sure if this is 100% correct so I'll not check it at the mo.
            break;

        default:
            throw new BookException(Msg.STRONGS_ERROR_TYPE, new Object[] { new Integer(number) });
        }
    }

    /**
     * This is a Hebrew word
     */
    public static final int HEBREW = 0;

    /**
     * This is a Greek word
     */
    public static final int GREEK = 1;

    /**
     * This is a Parsing note
     */
    public static final int PARSING = 2;

    /**
     * This largest legal value for a Greek number
     */
    public static final int GREEK_MAX = 5624;

    /**
     * This largest legal value for a Hebrew number
     */
    public static final int HEBREW_MAX = 8674;

    /**
     * The type of this Strongs number
     */
    private int type;

    /**
     * The actual number itself
     */
    private int number;
}

--- NEW FILE: StudyTool.java ---
package org.crosswire.jsword.book;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.crosswire.common.util.Logger;
import org.crosswire.jsword.book.search.basic.DefaultSearchRequest;
import org.crosswire.jsword.passage.Key;
import org.crosswire.jsword.passage.NoSuchKeyException;
import org.jdom.Element;

/**
 * StudyTool is-an extension to Bible that knows about the original
 * Greek/Hebrew in the form of Strongs numbers.
 * 
 * <p><table border='1' cellPadding='3' cellSpacing='0'>
 * <tr><td bgColor='white' class='TableRowColor'><font size='-7'>
 *
 * Distribution Licence:<br />
 * 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.<br />
 * 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.<br />
 * The License is available on the internet
 * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, or by writing to:
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA<br />
 * The copyright to this program is held by it's authors.
 * </font></td></tr></table>
 * @see gnu.gpl.Licence
 * @author Joe Walker [joe at eireneh dot com]
 * @version $Id: StudyTool.java,v 1.1 2005/04/01 17:09:46 dmsmith Exp $
 */
public class StudyTool
{
    /**
     * StudyTool: For a given word find a list words it is translated from
     * @param word The text to search for
     * @return The source numbers of that word
     */
    public Collection getTranslations(Book bible, String word) throws BookException
    {
        Key key = bible.find(new DefaultSearchRequest(word, null));
        BookData data = bible.getData(key);

        Map reply = new HashMap();

        // Loop through all the divs in this BookData
        Iterator oit = data.getOsis().getChild(OSISUtil.OSIS_ELEMENT_OSISTEXT).getChildren(OSISUtil.OSIS_ELEMENT_DIV).iterator();
        while (oit.hasNext())
        {
            Element div = (Element) oit.next();

            // And loop over the content in this div
            Iterator dit = OSISUtil.getDeepContent(div, OSISUtil.OSIS_ELEMENT_W).iterator();
            while (dit.hasNext())
            {
                // LATER(joe): This only looks at L1 content, we need a deep scan for 'W's.
                Object ele = dit.next();
                Element w = (Element) ele;
                String content = OSISUtil.getPlainText(w);

                // There will be many words in the passage in question,
                // but not all of them will be translations of our word
                if (content.indexOf(word) != -1)
                {
                    Strongs strongs = new Strongs(w);

                    Translation trans = (Translation) reply.get(strongs);
                    if (trans == null)
                    {
                        try
                        {
                            trans = new Translation(word, strongs, bible.getKey(null));
                        }
                        catch (NoSuchKeyException ex)
                        {
                            log.warn("Failed to create key", ex); //$NON-NLS-1$
                        }

                        reply.put(strongs, trans);
                    }

                    trans.getKey().addAll(OSISUtil.getVerse(w));
                }
            }
        }

        return reply.values();
    }

    /**
     * StudyTool: For a given number find a list of ways it is translated
     * @param number The strongs number to search for
     * @return The words that the number is translated to
     */
    public Collection getTranslations(Book bible, Strongs number) throws BookException
    {
        Key key = bible.find(new DefaultSearchRequest(number.getOLBName(), null));
        BookData data = bible.getData(key);

        Map reply = new HashMap();

        // Loop through all the divs in this BookData
        Iterator oit = data.getOsis().getChild(OSISUtil.OSIS_ELEMENT_OSISTEXT).getChildren(OSISUtil.OSIS_ELEMENT_DIV).iterator();
        while (oit.hasNext())
        {
            Element div = (Element) oit.next();

            // And loop over the content in this div
            Iterator dit = OSISUtil.getDeepContent(div, OSISUtil.OSIS_ELEMENT_W).iterator();
            while (dit.hasNext())
            {
                // see note above on deep scanning for W
                Object ele = dit.next();
                Element w = (Element) ele;
                Strongs strongs = new Strongs(w);

                // There will be many strongs number in the passage in
                // question, but not all of them will be translations of our
                // strongs number
                if (strongs.equals(number))
                {
                    String translated = OSISUtil.getPlainText(w);

                    Translation trans = (Translation) reply.get(translated);
                    if (trans == null)
                    {
                        try
                        {
                            trans = new Translation(translated, number, bible.getKey(null));
                        }
                        catch (NoSuchKeyException ex)
                        {
                            log.warn("Failed to create key", ex); //$NON-NLS-1$
                        }

                        reply.put(translated, trans);
                    }

                    trans.getKey().addAll(OSISUtil.getVerse(w));
                }
            }
        }

        return reply.values();
    }

    /**
     * The log stream
     */
    protected static final Logger log = Logger.getLogger(StudyTool.class);
}



More information about the jsword-svn mailing list