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(); } }
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:\ PSEOn 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
javac Person.javaCase 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.
On Windows, to run the postprocessor, enter
osjcfp -dest ..\osjcfpout Person.classOn UNIX, to run the postprocessor, enter
osjcfp -dest ../osjcfpout Person.classThe -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.
Run the program as a Java application. Here is a typical command line:
java COM.odi.demo.people.Person person.odbThe 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.
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.
Updated: 05/13/97 12:17:04