PSE/PSE Pro for Java API User Guide

Example of Using PSE/PSE Pro

This chapter provides a simple example of a complete PSE/PSE Pro program. The code for this example is in the COM\odi\demo\people directory provided with PSE/PSE Pro.

Overview of Required Components

The sample program stores some information about a few people and then retrieves some of the information from the database and displays it. The program shows the components you must include in your application so that it can use PSE/PSE Pro. These components are

When you write a PSE/PSE Pro program you write it as though classes are persistence-capable. However, a program cannot store objects persistently until you run the PSE/PSE Pro-provided class file postprocessor. The postprocessor generates annotated versions of the class files. The annotated version of the class definition is persistence-capable. You run the postprocessor after you compile the program and before you run the program.

Sample Code

package COM.odi.demo.people;
// Import the COM.odi package, which contains the API:
import COM.odi.*;
public
class Person {
      // Fields in the Person class:
      String name;
      int age;
      Person children[];
      // Main:
      public static void main(String argv[]) {
            String dbName = argv[0];
            // The following line initializes the PSE/PSE Pro software.
            // Currently, PSE/PSE Pro ignores the arguments.
            ObjectStore.initialize(null, null);
            Database db = createDatabase(dbName);
            readDatabase(db);
      }
      static Database createDatabase(String dbName) {
            // Attempt to open and destroy the database specified on the
            // command line. This ensures that the program creates a
            // new database each time the application is called.
            try {
                  Database.open(dbName, ObjectStore.OPEN_UPDATE).destroy();
            }      catch (DatabaseNotFoundException e) {
            }
            // Call the Database.create() method to create a new database.
            Database db = Database.create(dbName, 
                                          ObjectStore.ALL_READ | ObjectStore.ALL_WRITE); 
            // Start an update transaction:
            Transaction tr = Transaction.begin(ObjectStore.UPDATE);
            // Create instances of Person:
            Person sophie = new Person("Sophie", 5, null);
            Person joseph = new Person("Joseph", 1, null);
            Person children[] = { sophie, joseph };
            Person tim = new Person("Tim", 35, children);
            // Create a database root and associate it with 
            // tim, which is a persistence-capable object.
            // PSE/PSE Pro uses a database root as an entry
            // point into a database. 
            db.createRoot("Tim", tim);
            // End the transaction. This stores the three person objects,
            // along with the String objects representing their names, and
            // the array of children, in the database. 
            tr.commit();
            return db;
      }
      static void readDatabase(Database db) {
            // Start a read-only transaction:
            Transaction tr = Transaction.begin(ObjectStore.READONLY);
            // Use the "Tim" database root to access objects in the 
            // database. Because tim references sophie and joseph,
            // obtaining the "Tim" database root allows the program 
            // also to reach sophie and joseph. In each transaction, an
            // application must obtain a database root and use it to 
            // navigate to persistent objects. 
            Person tim = (Person)db.getRoot("Tim");
            Person children[] = tim.getChildren();
            System.out.print("Tim is " + tim.getAge() + " and has " + 
                              children.length + " children named: ");
            for (int i=0; i < children.length; i++) {
                  String name = children[i].getName();
                  System.out.print(name + " ");
            }
            System.out.println("");
            // End the read-only transaction. 
            // This form of the commit method ends the accessibility
            // of the persistent objects and abandons the transient 
            // objects.
            tr.commit();
      }
      // Constructor:
      public Person(String name, int age, Person children[]) {
             this.name = name; this.age = age; this.children = children;
      }
      public String getName() { return name; }
      public void setName(String name) { this.name = name; }
      public int getAge() { return age; }
      public void setAge(int age) { this.age = age; }
      public Person[] getChildren() { return children; }
      public void setChildren(Person children[]) {
                  this.children = children;
      }
      // This class is never used as a persistent hash key, so
      // include the following definition. If you do not, then 
      // when you run the postprocessor it is unclear whether or
      // not you intend to use the class as a hash code. 
      // Consequently, the postprocessor inserts a hashCode 
      // function for you. The following definition avoids this.
      public int hashCode() {
            return super.hashCode();
      }
}

Before You Run the Program

Before you can run the sample program, you must

Adding Entries to CLASSPATH

In your CLASSPATH environment variable, you already have two entries related to PSE/PSE Pro:

Ensure that these zip files are explicitly in your class path. An entry for the directory containing them is not sufficient.

Two more entries are required for you to be able to build and run the program. The first entry enables PSE/PSE Pro to locate the annotated class files when you run the program. The second entry establishes the location of the source files being compiled.

The order of these two entries is significant. The entry that establishes the location of the annotated classes must precede the entry that establishes the location of the source files. This sequence ensures that when you run the program PSE/PSE Pro finds the annotated class definitions rather than the unannotated definitions.

For example, on Windows, if you place the PSE distribution in the c:\PSE directory, you need the following entries:

c:\PSE\pse.zip;c:\PSE\tools.zip;c:\PSE\COM\odi\demo\osjcfpout;c:\
PSE
On UNIX, if you place the PSE Pro distribution in /usr/local/pro, you need:

/usr/local/pro/pro.zip:/usr/local/pro/tools.zip:/usr/local/pro/COM/odi
/demo/osjcfpout:/usr/local/pro

Compiling the Program

To compile the program, change to the COM/odi/demo/people directory and enter

javac Person.java
Case is significant for the file name, so you must specify Person.java and not person.java.

As output, the javac compiler produces the run-time byte code file Person.class.

Running the Postprocessor

You must run the class file postprocessor to make the Person class persistence-capable. The postprocessor generates new annotated files in a directory that you specify. After you run the postprocessor your program uses the annotated class files and not the original class files. Ensure that the bin directory that contains the osjcfp executable is in your path, as noted in the top-level README file and the postprocessor documentation.

On Windows, to run the postprocessor, enter

osjcfp -dest ..\osjcfpout Person.class
On UNIX, to run the postprocessor, enter

osjcfp -dest ../osjcfpout Person.class
The -dest option specifies a destination directory for the annotated files. The argument for this option is the same as the directory in your CLASSPATH environment variable that establishes the location of the annotated files. Normally, you must explicitly create this directory before you run the postprocessor. But this example is provided as a demo program and the directory is created for you as part of the installation procedure.

The result from the osjcfp command shown above is the annotated class file osjcfpout\COM\odi\demo\people\Person.class.

Running the Program

Before you run the program, ensure that the PSE/PSE Pro lib directory is in your library search path.

Run the program as a Java application. Here is a typical command line:

java COM.odi.demo.people.Person person.odb
The argument is the pathname of the database's .odb file, namely person.odb. The application also creates person.odt, and these two files form the database. You can specify any path name you want, as long as the file name ends with .odb. This example uses a relative path name, so PSE/PSE Pro creates the files in the working directory.

The expected output is

Tim is 35 and has 2 children named: Sophie Joseph

Also, the example application creates or replaces the person.odb database in the current directory.



[previous] [next]

doc@odi.com
Copyright © 1997 Object Design, Inc. All rights reserved.

Updated: 05/13/97 12:17:04