Monk Datastore Overview

prev     tcon     next

Programming with Core Objects

Use the public javadoc for the package edu.northwestern.at.monk.model when you write code. The tree view of the package is particularly useful.

You must call the initialization method ModelInit.init before you can use the model. For example:


    /** The main program.
     *
     *  @param  args        Command line arguments.
     */

    public static void main (String[] args) {
    
        try {
        
            ModelInit.init(
                "com.mysql.jdbc.Driver",            // JDBC driver class name
                "jdbc:mysql://scribe.at.northwestern.edu/monk?characterEncoding=UTF-8",
                                                    // Database URL
                "monk",                             // Database username
                "monk",                             // Database password
                100                                 // Max # concurrent connections
            );
            
            //  Now you can use the model.
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

The initialization method reads all the core objects into memory for efficient access. This includes all the lemmas and all the spellings, which can be large collections. This can take a long time.

This architecture optimizes the model for use in the Monk server, which presumably has a large amount of memory, is started infrequently, and is running on the same host as the underlying database. It is not optimal for end-user application programs which need to access the data. These programs are written to the Monk server API, not to the model API described here. Only the Monk server uses the model package directly.

Each core object has getter methods for accessing the attributes of the object. Each core object class also has a static method named getAll for getting all the objects of the class, and a static method named get for getting an object given its tag.

All core objects are immutable. The initialization method constructs all of them. There are no public constructors, factory methods, or setter methods. There is only one copy of each object in memory. You may check for equality of core objects using the == operator. There is no need to use the equals method.

All of the core object classes implement the interface Comparable<T>. Their compareTo methods define "natural" orderings, typically case and diacritical-insensitive increasing alphabetical orderings by tag, title, or name. The getAll methods return their collections in this "natural" order. Each of the classes also has static sort methods that can be used to sort arrays and collections of objects using other orderings, on both single and multiple attribute columns, and static find methods used to search for objects.

The model package is thread safe.

Note that words (objects of the class Word) are not core objects. We'll discuss words and their parts later.

The model package requires Java 1.5 or later. It makes significant use of all of the new features of Java 1.5, including generics (paramaterized types).

All of the examples using core objects presented below are very efficient. Because all the core objects are read into memory at initialization, none of these examples require any kind of database searching or disk access.

Example 1: Print a table of contents for a datastore.


/** Prints a table of contents. */

void printTableOfContents () {
    Collection<Corpus> corpora = Corpus.getAll();
    for (Corpus corpus : corpora) {
        System.out.println(corpus.getTitle());
        Collection<Work> works = corpus.getWorks();
        for (Work work : works) {
            System.out.println("   " + work.getTitle());
            List<Author> authors = work.getAuthors();
            for (Author author : authors) {
                System.out.println("      " + author.getName());
            }
        }
    }
}

Example 2: Given a collection of work part tags, print their titles and levels.


/** Prints titles and levels for a collection of work part tags.
 *
 *  @param  tags        Collection of tags.
 */
 
void printWorkPartTitlesAndLevels (Collection<String> tags) {
    for (String tag : tags) {
        WorkPart workPart = WorkPart.get(tag);
        if (workPart == null) {
            System.out.println("There is no work part with tag: " + tag);
        } else {
            System.out.println(
                "tag = " + tag + 
                ", title = " + workPart.getTitle() + 
                ", level = " + workPart.getLevel()
            );
        }
    }
}

Example 3: Print the table of contents for a work


/** Prints the table of contents for a work.
 *
 *  @param  work    Work.
 */
 
void printWorkTableOfContents (Work work) {
    printWorkPartTableOfContents(work);
}

/** Prints the table of contents for a work part.
 *
 *  @param  workPart    Work part.
 */
 
void printWorkPartTableOfContents (WorkPart workPart) {
    for (int i = 0; i < workPart.getLevel(); i++) System.out.print("   ");
    System.out.println(workPart.getTitle());
    List<WorkPart> children = workPart.getChildren();
    for (WorkPart child : children) 
        printWorkPartTableOfContents(child);
}

Note the use of recursion to traverse the work part tree rooted at the work, and that this code relies on the fact that Work is a subclass of WorkPart.

An easier way to do the same thing is to use the convenience method WorkPart.getDescendants(). This method returns all the descendants of a work part, including the work part itself, in preorder traversal:


/** Prints the table of contents for a work.
 *
 *  @param  work    Work.
 */
 
void printWorkTableOfContents2 (Work work) {
    for (WorkPart workPart : work.getDescendants()) {
        for (int i = 0; i < workPart.getLevel(); i++) System.out.print("   ");
        System.out.println(workPart.getTitle());
    }
}

Example 4: Print a table of all the parts of speech.


/** Prints a table of all the parts of speech. */

void printPos () {
    Collection<Pos> allPos = Pos.getAll();
    for (Pos pos : allPos) {
        System.out.println(pos.getTag());
        System.out.println("   word class = " + pos.getWordClass().getTag());
        printCategory(pos.getSyntaxCategory(), "syntax");
        printCategory(pos.getTenseCategory(), "tense");
        printCategory(pos.getMoodCategory(), "mood");
        printCategory(pos.getCaseCategory(), "case");
        printCategory(pos.getPersonCategory(), "person");
        printCategory(pos.getNumberCategory(), "number");
        printCategory(pos.getDegreeCategory(), "degree");
        printCategory(pos.getNegativeCategory(), "negative");
    }
}

/** Prints a part of speech category.
 *
 *  @param  category    Category, or null if none.
 *
 *  @param  label       Label.
 */
 
void printCategory (TaggedObject category, String label) {
    System.out.print("   " + label + " = ");
    System.out.println(category == null ? "none" : category.getTag());
}

Note the use of the base class TaggedObject, which implements the getTag method. All of the core objects extend this base class.

prev     tcon     next