ObjectStore Java Tutorial

Appendix A

Source Code

This chapter provides the source code for the following Personalization application classes:

Source Code for Interest.java

Source Code for User.java

Source Code for UserManager.java

Source Code for TestDriver.java

Source Code for PersonalizationException.java

Source Code for Interest.java

package COM.odi.tutorial;
import COM.odi.*;
/**
 * The Interest class models a particular interest that a user may
 * have. It contains a name and a value. For example, the name of
 * an interest might be "food" and the value might be "pizza".
 */
public class Interest
{
      /* the name of the interest */
      private String name;
      /* the value of the interest */
      private String value;
      /* the user who has this interest */
      private User user;
      /* accessor functions */
      public String getName() { return name; }
      public String getValue() { return value; }
      public void setValue(String value) { this.value = value; }
      public User getUser() { return user; }
      /**
       * Constructs a new interest object given a name and a value
       */
      public Interest(String name, String value, User user)
      {
            this.name = name;
            this.value = value;
            this.user = user;
      }
      /*
       * Destroy the interest's associated objects
       */
      public void preDestroyPersistent()
      {
            if (!ObjectStore.isDestroyed(name))
                  ObjectStore.destroy(name);
            if (!ObjectStore.isDestroyed(value))
                  ObjectStore.destroy(value);
      }
}

Source Code for User.java

package COM.odi.tutorial;
import java.util.*;
import COM.odi.*;
import COM.odi.util.*;
/**
 * The User class models users. Users have names, email addresses,
 * and PINS. Each user also has a set of interests. The application
 * uses PINs to validate a user's identity.
 */
public
class User {
      /* The name of the user */
      private String name;
      /* The user's email address */
      private String email;
      /* The user's Personal Identification Number */
      private int PIN;
      /* The set of user's interests */
      private OSHashMap interests;
      /* accessors */
      public String getName() { return name; }
      public String getEmail() { return email; }
      public int getPIN() { return PIN; }
      public Map getInterests() { return interests; }
      /**
       * Constructs a user object given the name, email and PIN
       */
      public User(String name, String email, int PIN) {
            this.name = name;
            this.email = email;
            this.PIN = PIN;
            this.interests = new OSHashMap(5); /* initial hashtable size */
      }
      /*
       * Destroy the associated objects
       */
      public void preDestroyPersistent() {
            if (!ObjectStore.isDestroyed(name))
                  ObjectStore.destroy(name);
            if (!ObjectStore.isDestroyed(email))
                  ObjectStore.destroy(email);
            /* destroy each of the interests */
            Iterator interestIter = interests.values().iterator();
            while (interestIter.hasNext()) {
                  Interest interest = (Interest) interestIter.next();
                  ObjectStore.destroy(interest);
            }
            /* destroy the interests list too */
            ObjectStore.destroy(interests);
      }
      /**
       * Add an interest to the User's list of interests.
       *
       * @param interestName the name of the interest
       * @param interestValue the value of the interest
       *
       * @exception PersonalizationException If the interest is
       * already there (the same name as another interest)
       */
      public Interest addInterest(String interestName, String interestValue)
                   throws PersonalizationException
      {
            Object previous = interests.get(interestName);
            if (previous != null)
                  throw new PersonalizationException("Interest already there: " +      interestName);
            Interest interest = new Interest(interestName, interestValue, this);
            interests.put(interestName, interest);
            return interest;
      }
      /**
       * Update an interest in the User's list of interests.
       *
       * @param interestName the name of the interest
       * @param interestValue the new value of the interest
       *
       * @exception PersonalizationException is thrown if the interest is
       * already not there.
       */
      public Interest changeInterest(String interestName, String interestValue)
                   throws PersonalizationException
      {
            Interest interest = (Interest)interests.get(interestName);
            if (interest == null)
                  throw new PersonalizationException("No such registered interest: " + interestName);
            interest.setValue(interestValue);
            return interest;
      }
      /**
       * Remove an interest from the User's list of interests.
       *
       * @param interestName The name of the Interest to remove.
       *
       * @exception PersonalizationException if the interest is not
       * found in the user's list of interests
       */
      public Interest removeInterest(String interestName)
                   throws PersonalizationException
      {
            Interest interest = (Interest)interests.remove(interestName);
            if (interest == null)
                  /* did not find the interest */
                  throw new PersonalizationException("Interest not found: " + name);
       return interest;
      }
}

Source Code for UserManager.java

package COM.odi.tutorial;
import java.util.*;
import java.io.*;
import COM.odi.*;
import COM.odi.util.*;
import COM.odi.util.query.*;
/**
 * The UserManager acts as the interface to the Personalization data
 * that is stored persistently. In real use, it might serve as an
 * application service that would receive requests (RMI or ORB
 * requests perhaps) and service those requests by accessing the
 * database.
 */
public
class UserManager
{
      /* The database that this UserManager is operating against. */
      private static Database db;
      /* The active session for this UserManager */
      private static Session session;
      /* The extent of all users in the database is held in a root.
             We use a map, whose key is the name of the user. */
      private static Map allUsers;
      /* The extent of all interests in the database is held in a root.
             We use a Set, which might have one or more indexes. */
      private static Set allInterests;
      /* This is used to allocate the Personal Identification Number (PIN) */
      private static Random pinGenerator;
      public static void initialize(String dbName)
      {
            /* initialize a random number generator to allocate PINs */
            pinGenerator = new Random();
            /* Create a session and join this thread to the new session. */
            session = Session.create(null, null);
            session.join();
            /* Open the database or create a new one if necessary. */
            try {
                  db = Database.open(dbName, ObjectStore.UPDATE);
            } catch (DatabaseNotFoundException e) {
                  db = Database.create(dbName, ObjectStore.ALL_READ | ObjectStore.ALL_WRITE);
            }
            /* Find the allUsers and allInterests roots or create them if not there. */
            Transaction tr = Transaction.begin(ObjectStore.UPDATE);
            try {
                  allUsers = (Map) db.getRoot("allUsers");
                  allInterests = (Set) db.getRoot("allInterests");
            } catch (DatabaseRootNotFoundException e) {
                  /* Create the database roots and give them appropriate values */
                  db.createRoot("allUsers", allUsers = new OSHashMap());
                  db.createRoot("allInterests", allInterests = new OSHashSet());
            }
            /* End the transaction and retain a handle to allUsers and allInterests */
            tr.commit(ObjectStore.RETAIN_HOLLOW);
            return;
      }
      /**
       * Close the database and terminate the session.
       */
      public static void shutdown()
      {
            db.close();
            session.terminate();
      }
      /**
       * Add a new user to the database; if the user's name already
       * exists, throw an exception.
       *
       * @param name: The name of the user to be added
       * @param email: The email address of the user
       *
       * @return The PIN of the new user.
       *
       * @exception PersonalizationException is thrown if the user
       * is already there.
       */
      public static int subscribe(String name, String email)
            throws PersonalizationException
      {
            Transaction tr = Transaction.begin(ObjectStore.UPDATE);
            /* First check to see if the user's name is already there. */
            if (allUsers.get(name) != null) {
                  tr.abort(ObjectStore.RETAIN_HOLLOW);
                  throw new PersonalizationException("User already there: " + name);
            }
            /* The user name is not there so add the new user;
                   first generate a PIN in the range 0..10000. */
            int pin = pinGenerator.nextInt() % 10000;
            if (pin < 0) pin = pin * -1;
            User newUser = new User(name, email, pin);
            allUsers.put(name, newUser);
            tr.commit(ObjectStore.RETAIN_HOLLOW);
            return pin;
      }
      /**
       * Removes the user from the database.
       *
       * @param name: The name of the user to be removed.
       *
       * @exception PersonalizationException is thrown if the user is
       * not found.
       */
      public static void unsubscribe(String name)
            throws PersonalizationException
      {
            Transaction tr = Transaction.begin(ObjectStore.UPDATE);
            User user = (User) allUsers.get(name);
            if (user == null) {
                  tr.abort(ObjectStore.RETAIN_HOLLOW);
                  throw new PersonalizationException ("Could not find user: " + name);
            }
            /* remove the user from the allUsers collection, and
             * remove all of the user's interests from the allInterests collection */
            allUsers.remove(name);
            Iterator interests = user.getInterests().values().iterator();
            while (interests.hasNext())
                  allInterests.remove(interests.next());
            /* finally destroy the user and all its subobjects */
            ObjectStore.destroy(user);
            tr.commit(ObjectStore.RETAIN_HOLLOW);
      }
      /**
       * Validates a username / PIN pair, and returns the user object.
       */
      public static User validateUser(String userName, int PIN)
      {
            Transaction tr = Transaction.begin(ObjectStore.READONLY);
            User user = (User) allUsers.get(userName);
            if (user == null) {
                  tr.abort(ObjectStore.RETAIN_HOLLOW);
                  throw new PersonalizationException ("Could not find user: " + userName );
            }
            if (user.getPIN() != PIN) {
                  tr.abort(ObjectStore.RETAIN_HOLLOW);
                  throw new PersonalizationException ("Invalid PIN for user: " + userName );
            }
            tr.commit(ObjectStore.RETAIN_READONLY);
            return user;
      }
      /**
       * Add an interest to an existing user's set of interests.
       *
       * @param userName: The name of the user.
       * @param interestName: The name of the interest to create.
       * @param interestValue: The value of the new interest.
       *
       * @exception PersonalizationException: thrown if the user is
       * not found or if the user already has this interest.
       */
      public static void addInterest(String userName, String interestName, String interestValue)
            throws PersonalizationException
      {
            Transaction tr = Transaction.begin(ObjectStore.UPDATE);
            User user = (User) allUsers.get(userName);
            if (user == null) {
                  tr.abort(ObjectStore.RETAIN_HOLLOW);
                  throw new PersonalizationException("User not found: " + userName);
            }
            else {
                  try {
                        Interest interest = user.addInterest(interestName, interestValue);
                        allInterests.add(interest);
                  } catch (PersonalizationException e) {
                        tr.abort(ObjectStore.RETAIN_HOLLOW);
                        throw e;
                  }
            }
            tr.commit(ObjectStore.RETAIN_HOLLOW);
            return;
      }
      /**
       * Remove an interest from a user's set of interests.
       *
       * @param userName: The name of the user.
       * @param interestName: The name of the interest to remove.
       *
       * @exception PersonalizationException: thrown if the user is
       * not found or the interest is not found.
       */
      public static void removeInterest(String userName, String interestName)
            throws PersonalizationException
      {
            Transaction tr = Transaction.begin(ObjectStore.UPDATE);
            User user = (User) allUsers.get(userName);
            if (user == null) {
                  tr.abort(ObjectStore.RETAIN_HOLLOW);
                  throw new PersonalizationException("User not found: " + userName);
            }
            else {
                  try {
                        Interest interest = user.removeInterest(interestName);
                        allInterests.remove(interest);
                        ObjectStore.destroy(interest);
                  } catch (PersonalizationException e) {
                        tr.abort(ObjectStore.RETAIN_HOLLOW);
                        throw e;
                  }
            }
            tr.commit(ObjectStore.RETAIN_HOLLOW);
            return;
      }
      /**
       * Update an interest in an existing user's set of interests.
       *
       * @param userName: The name of the user.
       * @param interestName: The name of the interest to modify.
       * @param interestValue: The new value of the interest.
       *
       * @exception PersonalizationException: thrown if the user is
       * not found or if the user does not already have this interest.
       */
      public static void changeInterest(String userName, String interestName, String interestValue)
            throws PersonalizationException
      {
            Transaction tr = Transaction.begin(ObjectStore.UPDATE);
            User user = (User) allUsers.get(userName);
            if (user == null) {
                  tr.abort(ObjectStore.RETAIN_HOLLOW);
                  throw new PersonalizationException("User not found: " + userName);
            }
            else {
                  try {
                        user.changeInterest(interestName, interestValue);
                  } catch (PersonalizationException e) {
                        tr.abort(ObjectStore.RETAIN_HOLLOW);
                        throw e;
                  }
            }
            tr.commit(ObjectStore.RETAIN_HOLLOW);
            return;
      }
      /**
       * Get the interests for a particular user.
       *
       * @param userName: The name of the user.
       *
       * @return a Set of interests.
       *
       * @exception PersonalizationException: thrown if the user is
       * not found.
       */
      public static Collection getInterests(String userName)
            throws PersonalizationException
      {
            Transaction tr = Transaction.begin(ObjectStore.READONLY);
            User user = (User) allUsers.get(userName);
            if (user == null) {
                  tr.abort(ObjectStore.RETAIN_HOLLOW);
                  throw new PersonalizationException ("User not found: " + userName);
            }
            /* recursively fetch all of the objects accessible from the users
             * set of interests, so that they can be returned and accessed
             * outside of a transaction */
            ObjectStore.deepFetch(user.getInterests());
            /* Commit using retain-readonly so the interests can be accessed
             * outside of this transaction. */
            tr.commit(ObjectStore.RETAIN_READONLY);
            return user.getInterests().values();
      }
      /**
       * Retrieves all of the users.
       *
       * @return an array containing the names of all registered users.
       *
       * @exception Exception:
       */
      public static String[] getUserNames()
      {
            Transaction tr = Transaction.begin(ObjectStore.READONLY);
            String[] names = new String[allUsers.size()];
            Iterator userIter = allUsers.values().iterator();
            int userIndex = 0;
            while (userIter.hasNext())
                  names[userIndex++] = ((User)userIter.next()).getName();
            tr.commit(ObjectStore.RETAIN_HOLLOW);
            return names;
      }
}

Source Code for TestDriver.java

package COM.odi.tutorial;
import COM.odi.util.*;
import java.util.*;
import java.io.*;
/**
 * The TestDriver class exercises the UserManager code. It
 * implements a simple UI that is driven by terminal I/O.
 */
public
class TestDriver
{
      /* Main: reads input commands from the terminal and exercises
       * the UserManager code.
       */
      public static void main(String argv[])
      {
            if (argv.length < 1) {
                  System.out.println("Usage: java TestDriver <databaseName>");
                  return;
            }
            /* the database to operate on is a command-line argument;
             * the file to read commands from is an optional second argument
             * (if no input file is specified, commands are read from System.in)
             */
            String dbName = argv[0];
            InputStream input = System.in;
            if (argv.length > 1)
                  try {
                  input = new FileInputStream(argv[1]);
            } catch (FileNotFoundException e){}
            /* initialize the UserManager, which opens the database */
            UserManager.initialize(dbName);
            /* read command input */
            BufferedReader instream = new BufferedReader(new InputStreamReader(input));
            /* print help message describing the legal commands */
            printHelp();
            while (true) {
                  try {
                        System.out.println();
                        /* read a line of command input */
                        String inputLine = instream.readLine();
                        if (inputLine == null) { /* end of input */
                              UserManager.shutdown();
                              return;
                        }
                        /* tokenize the command input with a StringTokenizer */
                        StringTokenizer tokenizer = new StringTokenizer(inputLine, "");
                        if (!tokenizer.hasMoreTokens()) continue;
                        String command = tokenizer.nextToken();
                        System.out.println();
            /* ******************* */
            /*HELP*/
            /* ******************* */
                        if ("help".startsWith(command)) {
                              printHelp();
                        }
            /* ******************* */
            /* SUBSCRIBE NEW USER*/
            /* ******************* */
                        else if ("subscribe".startsWith(command)) {
                              int PIN = UserManager.subscribe(readString(tokenizer) /*userName */,
                                    readString(tokenizer) /*userEmail */);
                              System.out.println("      Your personal identification number is " + PIN);
                        }
            /* ******************* */
            /*      UNSUBSCRIBE USER       */
            /* ******************* */
                        else if ("unsubscribe".startsWith(command)) {
                              UserManager.unsubscribe(readString(tokenizer) /* userName */);
                        }
            /* ******************* */
            /*      VALIDATE USER PIN      */
            /* ******************* */
                        else if ("validate".startsWith(command)) {
                              User usr = UserManager.validateUser(readString(tokenizer) /*userName */,
                                    readInt(tokenizer) /* PIN*/);
                              System.out.println("      User name " + usr.getName());
                              System.out.println("            PIN: " + usr.getPIN());
                              System.out.println("            email: " + usr.getEmail());
                        }
            /* ******************* */
            /*       LIST ALL USERS            */
            /* ******************* */
                        else if ("listusers".startsWith(command)) {
                              String[] names = UserManager.getUserNames();
                              if (names.length == 0)
                                    System.out.println("      There are no registered users.");
                              for (int i = 0; i<names.length; i++) {
                                    System.out.println("      " + names[i]);
                              }
                        }
            /* ******************* */
            /*       ADD AN INTEREST       */
            /* ******************* */
                        else if ("addinterest".startsWith(command)) {
                              UserManager.addInterest(readString(tokenizer) /* userName */,
                                    readString(tokenizer) /* interest name */,
                                    readString(tokenizer) /* interest value */);
                        }
            /* ******************* */
             /* REMOVE AN INTEREST */
            /* ******************* */
                        else if ("removeinterest".startsWith(command)) {
                              UserManager.removeInterest(readString(tokenizer) /* userName */,
                                                                                                             readString(tokenizer) /* interest name */);
                        }
            /* ******************* */
            /*      CHANGE AN INTEREST */
            /* ******************* */
                        else if ("changeinterest".startsWith(command)) {
                              UserManager.changeInterest(readString(tokenizer) /* userName */,
                                    readString(tokenizer) /* interest name */,
                                          readString(tokenizer) /* interest value */);
                        }
            /* ******************* */
            /* LIST USER INTERESTS */
            /* ******************* */
                        else if ("interests".startsWith(command)) {
                              String userName = readString(tokenizer);
                              Collection interests =
                                    UserManager.getInterests(userName);
                              Iterator iter = interests.iterator();
                              if (!iter.hasNext())
                                    System.out.println("      " + userName + " has no registered interests.");
                              while (iter.hasNext()) {
                                    Interest i = (Interest)iter.next();
                                    System.out.println("      " + i.getUser().getName() + " is interested in " +
                                          i.getName() + ": " + i.getValue());
                              }
                        }
            /* ******************* */
            /*            EXIT PROGRAM             */
            /* ******************* */
                        else if ("exit".startsWith(command)) {
                              UserManager.shutdown();
                              return;
                        }
            /* ******************** */
            /* UNRECOGNIZED COMMAND */
            /* ******************** */
                        else {
                              System.out.println("      Command not recognized.      Try \"help\"");
                        }
                  } catch (PersonalizationException e) {
                        System.out.println("      " + e.toString());
                  }
                  catch (Exception e) {
                        System.out.println("      " + e.toString());
                        UserManager.shutdown();
                        return;
                  }
            }
       }
      static void printHelp()
      {
            System.out.println();
            System.out.println("Each command consists of the command name, 
                  and a (possibly empty)");
            System.out.println("list of arguments, separated by spaces.");
            System.out.println();
            System.out.println("Legal commands are:");
            System.out.println("help // print this message");
            System.out.println("subscribe <username> <email> 
                  // enter a new user into the db");
            System.out.println("unsubscribe <username>      
                  // remove a user from the db");
            System.out.println("validate <username> <PIN>            
                  // validate PIN and display user data");
            System.out.println("listusers // list all users");
            System.out.println("addinterest <username> <interestname> <value>
                  // register an interest ");
            System.out.println("removeinterest <username> <interestname>
                  // unregister an interest ");
            System.out.println("changeinterest <username> <interestname> <value>      
                  // change an interest ");
            System.out.println("interests <username>       //display all interests for a user");
            System.out.println("exit// exit the program");
      }
      static String readString(StringTokenizer tokenizer)
      {
            if (tokenizer.hasMoreElements())
                  return tokenizer.nextToken();
            else
                  throw new PersonalizationException("unexpected end of command input");
      }
      static int readInt(StringTokenizer tokenizer)
      {
            if (tokenizer.hasMoreElements()) {
                  String token = tokenizer.nextToken();
                  try {
                        return Integer.valueOf(token).intValue();
                  } catch (NumberFormatException e) {
                        throw new PersonalizationException(
                              "Number Format Exception reading \"" + token + "\"");
                  }
            }
            else
                  throw new PersonalizationException("unexpected end of command input");
      }
}

Source Code for PersonalizationException.java

package COM.odi.tutorial;
import java.util.*;
/**
 * The PersonalizationException is thrown when certain error
 * conditions arise. For example
 *   -- a uid is not found
 *   -- a user already exists in the database
 *   -- an interest is not found
 *   -- an interest already exists in the user's set of interests
 */
public final class PersonalizationException extends RuntimeException 
{
      public PersonalizationException (String message) {
            super (message);
      }
}


[previous] [next]

Copyright © 1998 Object Design, Inc. All rights reserved.

Updated: 10/07/98 07:06:01