15.2. Persistent Model Package

The following sections look at each of the persistence-capable classes.

15.2.1. Publication class

This is the base class of books and CDs in the library.

Package com.corejdo.casestudy.model;
import java.util.Date ;
import java.util.Collection ;
import javax.jdo.*;

/**
 * This class contains generic
 * information common to all sorts of publications.
 *
 * <BR><FONT Color="red"><B>Persistent</B></FONT>
 */
public abstract class Publication
{
    /**
     * The title of the publication.
     */
    public String title;
    /**
     * Date, when the publication was published.
     */
    public Date published;
    /**
     * Date, when the publication was first published.
     */
    public Date firstPublished;
    /**
     * A copyright text.
     */
    public String copyright;

    /**
     * The librarian who maintained the publication.
     */
    public User insertedBy;

    public Publication() {
    }

    public String toString()
    {
        return "
 Title: "+title+
        "
 Published: "+published+
        "
 First published: "+firstPublished+
        "
 Copyright: "+copyright;
    }

    public String toHTMLTitle(String linkPrefix)
    {
        return "<TD CLASS=pubTitle>"+title+"</TD>";
    }

    public String toHTMLRest(String linkPrefix)
    {
        return
        "<TD CLASS=pubPubFirst>"+firstPublished+"</TD>"+
        "<TD CLASS=pubCopyright>"+copyright+"</TD>";
    }
    public abstract String toHTML(String linkPrefix);

The getCopies() method encapsulates the JDO query to find all the Copy instances that reference a Book instance. Encapsulating a query in this way is a useful practice, although some may prefer to put these types of methods in a separate, associated class to avoid having any JDO-dependent code in their persistence classes.

About toHTML() methods

The classes shown here include methods like toHTML(), toHTMLTitle(), and toHTMLRest(), for the sake of simplicity and easily readable comprehensive examples.

Most real-world domain classes, however, would not include such presentation layer-related methods and put view-related code into separate classes.


15.2.2. Book class

This class represents a Book.

Package com.corejdo.casestudy.model;

/**
 * This class contains data about books,
 * like author, International Standard Book Number (ISBN).
 */

public class Book
    extends Publication
{
    /**
     * International standard book number.
     */
    public String ISBN;
    /**
     * Author of the book.
     */
    public String author;

    public Book() {

    }

    public String toString()
    {
        return super.toString()+
        "
 ISBN: "+ISBN+
        "
 Author: "+author;
    }
    public String toHTML(String linkPrefix)
    {
        return "<TR CLASS=Book>"+toHTMLTitle(linkPrefix)+
        "<TD CLASS=BookAuthor>"+author+"</TD>"+
        "<TD CLASS=BookISBN>"+ISBN+"</TD>"+
        toHTMLRest(linkPrefix)+"</TR>";
    }
}

15.2.3. CD class

This class represents a CD. It is more complicated than the Book class because it provides more functionality. It contains a song list that is returned in toString and toHTML.

It shows basic collection operations with ArrayList.

Package com.corejdo.casestudy.model;

import java.util.*;
/**
 *
 * <BR><FONT Color="red"><B>Persistent</B></FONT>
 */
public class CD
    extends Publication
{

    List songs = new ArrayList(); // contains Song objects
    String referenceNumber;       // CD reference number
    public CD(String referenceNumber)
    {
        this.referenceNumber = referenceNumber;
    }

    private CD()
    {
    }

    public void addSong(String composer,
                        String title, int seconds)
    {
        songs.add(new Song(composer, title, seconds));
    }

    public String songTable()
    {
        StringBuffer buf = new StringBuffer();
        buf.append("<TABLE class=song>
");
        Iterator iter = songs.iterator();
        while (iter.hasNext()) {
            Song song = (Song)iter.next();
            buf.append("<TR class=song>");
            buf.append("<TD class=songTitle>");
            buf.append(song.title);
            buf.append("</TD>");
            buf.append("<TD class=songComposer>");
            buf.append(song.composer);
            buf.append("</TD>");
            buf.append("<TD class=songLength>");
            buf.append(song.length());
            buf.append("</TD>");
            buf.append("</TR>");
        }
        buf.append("</TABLE>
");
        return buf.toString();
    }

    public String toString()
    {
        StringBuffer buf = new StringBuffer();
        buf.append("CD: ");
        buf.append(this.referenceNumber);
        buf.append(super.toString());
        Iterator iter = songs.iterator();
        while (iter.hasNext()) {
            Song song = (Song)iter.next();
            buf.append(song);
            buf.append(", ");
        }
        return buf.toString();
    }

    public String toHTML(String linkPrefix)
    {
        return "<TR CLASS=CD>"+toHTMLTitle(linkPrefix)+
          "<TD VALIGN=TOP>"+songTable()+"</TD>"+
          "<TD VALIGN=TOP></TD>"+
          super.toHTMLRest(linkPrefix)+"</TR>";
    }
}

15.2.4. Copy class

The Copy class represents a physical copy of a particular publication. For example, a book on a library shelf is represented as an instance of the Copy class. This class has a reference back to Publication. An alternative model to this would use a collection of Copy instances in the Publication class. The benefit of this approach is that if there are a large number of instances, maintaining a collection of all of them can become problematic.

Package com.corejdo.casestudy.model;

import java.util.Date;

/**
 * A copy is the instance of a publication in a
 * library. A copy can be located somewhere in the
 * library or it can be borrowed by someone.
 * Other states of a copy can be: missing, damaged or sold.
 * A copy cannot be reserved by someone, only
 * publications can be reserved.
 *
 * <BR><FONT Color="red"><B>Persistent</B></FONT>
 */

public class Copy
{
    /**
     * The publication of which this is the instance of.
     */
    public Publication copyOf;

    /**
     * This flag is set when the borrowing time is over.
     */
    public boolean missing;
    /**
     * If the copy is damaged, this flag is set.
     */
    public boolean damaged;
    /**
     * If someone bought the copy, this flag is set.
     */
    public boolean sold;
    /**
     * Location of the copy in the library.
     */
    public String location;
    /**
     * Reference to the borrower. If set, this publication instance is borrowed
     * by someone.
     */
    public User borrower;
    /**
     * Date when the copy was borrowed.
     * Depending on the user policies of the
     * library.
     */
    public Date borrowDate;
    /**
     * Date when the copy should be returned
     * to the library.
     */
    public Date returnDate;

    public Copy(Publication copyOf)
    {
        this.copyOf = copyOf;
        this.location = "entry";
    }

    private Copy()
    {
    }
}

15.2.5. User class

The User class identifies a borrower and is used to define user rights or access restrictions.

Package com.corejdo.casestudy.model;

/**
 * A user object represents a user of the
 * library. That may be either a
 * borrower or a librarian (or both).
 *
 * <BR><FONT Color="red"><B>Persistent</B></FONT>
 */
public class User
{
    public User()
    {
    }
    /**
     * Name of user.
     */
    private String firstName;
    /**
     * Name of user.
     */
    private String lastName;
    /**
     * Cleartext password.
     */
    private String password;
    /**
     * Internally used user id.
     */
    private String id;
    /**
     * The rights of the user.
     */
    private Rights rights;

    public String getFirstName()
    {
        return firstName;
    }
    public void setFirstName(String firstName)
    {
        this.firstName = firstName;
    }
    public void setLastName(String lastName)
    {
        this.lastName = lastName;
    }
    public String getLastName()
    {
        return lastName;
    }
    public void setPassword(String password)
    {
        this.password = password;
    }
    public String getId()
    {
        return id;
    }
    public void setId(String id)
    {
        this.id = id;
    }

    public boolean checkPassword(String pw)
    {
        return pw.equals(password);
    }

    public Rights getRights()
    {
        if (rights == null) rights = new Rights();
        return rights;
    }

    public String toString()
    {
        return firstName+" "+lastName;
    }
}

15.2.6. Right and Rights classes

The Right class is an example of the Enumeration Pattern. It implements a tri-state enumeration (ALLOWED, DENIED, DEFAULT). The Right class itself cannot be made persistent, because the JDO Implementation will not be able to return the constant references for ALLOWED, DENIED and DEFAULT, which are static objects.

Package com.corejdo.casestudy.model;

/**
 * A transient tri-state value.
 * It may be set either to allow, deny or default.
 * <BR><B>not persistent</B>
 */
public final class Right
{

    boolean isAllowed(Right def)
    {
        if (this != DEFAULT) return this == ALLOWED;
        if (def == null || def == DEFAULT) return false;
        return def == ALLOWED;
    }

    boolean isDenied(Right def)
    {
        if (this != DEFAULT) return this == DENIED;
        if (def == null || def == DEFAULT) return true;
        return def == DENIED;
    }

    public static Right DENIED = new Right(-1);
    public static Right ALLOWED = new Right(1);
    public static Right DEFAULT = new Right(0);

    private int code;

    private Right(int code)
    {
        this.code = code;
    }
}

The Rights class maps the static Right objects to appropriate integer values:

package com.corejdo.casestudy.model;

import javax.jdo.InstanceCallbacks;
import javax.jdo.JDOHelper;
/**
 * Defines access restrictions for users and
 * user groups of the library.
 *
 * This is an example for a type mapping:
 * Instead of defining another persistent
 * class Right, the tri-state values
 * (allow, deny, default) are coded into plain
 * integer values, (+1, -1, 0 respectively).
 * For a better programming model, the
 * Right class is exposed to the application,
 * but stored internally as integer
 * values.
 *
 * <BR><FONT Color="red"><B>Persistent</B></FONT>
 */
public class Rights
    implements Cloneable
{
    /**
     * The right to add, remove or
     * modify users of the library.
     */
    private int _modifyUser;

    /**
     * The right to borrow something.
     */
    private int _borrow;

    /**
     * The right to manage publications.
     */
    private int _manage;



    /**
     * The constructor creates a default Rights object.
     * (An unauthorized user.)
     */

    public Rights()
    {
    }

    private int rightToInt(Right r)
    {
        if (r == Right.ALLOWED) return 1;
        if (r == Right.DEFAULT) return 0;
        if (r == Right.DENIED) return –1;
        throw new RuntimeException("Illegal value: "+r);
    }

    private Right intToRight(int i)
    {
        if (i == 1) return Right.ALLOWED;
        if (i == 0) return Right.DEFAULT;
        if (i == -1) return Right.DENIED;
        throw new RuntimeException("Illegal value: "+i);
    }

    public boolean canBorrow()
    {
        return intToRight(
                   _borrow).isAllowed(Right.ALLOWED);
    }
    public boolean canManage()
    {
        return intToRight(_manage).isAllowed(Right.DENIED);
    }
    public boolean canModifyUser()
    {
        return intToRight(
                   _modifyUser).isAllowed(Right.DENIED);
    }

    public void setBorrow(Right right)
    {
        _borrow = rightToInt(right);
    }

    public void setManage(Right right)
    {
        _manage = rightToInt(right);
    }

    public void setModifyUser(Right right)
    {
        _modifyUser = rightToInt(right);
    }

    public Rights copy()
    {
        try {
            int k = this._borrow;
            Rights r = (Rights)this.clone();
            return r;
        }
        catch (CloneNotSupportedException c) {
            throw new RuntimeException("Unexpected: "+c);
        }
    }

    public String toString()
    {
        String res =
         ( canBorrow() ? "borrow" : "noborrow")+
         ( canManage() ? ",manage" : ",nomanage")+
         ( canModifyUser() ? ",modify" : ",nomodify");
        return res;
    }
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset