Step 04: Java Databases The dialogue manager needs to be told which referring expressions can be resolved by database lookup. In step 3, we showed how this can be done using an MS Access database. This step illustrates how the concepts in the ontology can be mapped onto java classes. This technique allows you to instantiate a set of objects in Java and to refer to them using natural language. The difference between representing objects in the domain in databases and in java classes lies in the fact that it is easier to represent and change state in Java classes than it is in databases. To get an idea, open the file <ariadne dir>/data/tutorial/step04/step04.adl and take a look at the constructs that start with the database keyword. Also, take a look at edu.cmu.cs.is.step04.Step04.java Database Conversion Rules When comparing the adl file from this step to the one from the last step, you will see a lot more database conversion rules. The structure of the additional database conversion rules is the same, except that the query protocol and the query language both are called ‘jpkg’ (short for Java Package) instead of ‘dao’ and ‘sql’, respectively. This means that the internal java protocol and the internal query language should be used to retrieve objects. In other words, the fact that java objects are queried instead of Sql databases is transparent to the dialogue manager. Note to C++ programmers: You can always program your own query protocol and query language to access databases. How this is done can be learned from the arditf_jpkg, arditf_dao and arditf_sql packages. Java Implementation Java provides generic mechanisms to query and set properties of objects. Called JavaBeans, this technique requires each compliant object to support two methods for each property of type T, namely public T getProperty() ; public void setProperty(T t); Another mechanism, called reflection, allows classes to determine at runtime which methods are defined for an object. These two techniques are at the heart of the database access to java objects. The idea is to consider a class definition of a JavaBean as a database definition with one table (representing the objects). The table contains the fields that can be accessed by the JavaBeans methods. For example, if we have a class definition along the lines of public class Lamp { public void public void public void setOnOff(bool); setBrightness(int); setName(String); public bool getOnOff(); public int getBrightness(); public String getName(); }; we consider this equivalent to a SQL database definition named ‘Lamp’ which contains one table, also called ‘lamp’, which in turn contains the four fields OnOff, Brightness and Name, of types bool, int and string, respectively. The DialoguePackageAdapter class provides generic mechanisms to query the objects, you just need to tell the query method where your objects are stored and how they can be accessed. This is what the method declaration abstract Object[] getObjects(String databaseName,String tableName); is for. It ensures that for each database and table in that database, the objects are returned. In the example implementation in Step04Package, the start() method will create all the objects for each database and store them in an array. The getObjects() method will then simply return the array of objects for the requested database and requested table. Another consideration is the declaration of the properties that should be accessible through database access. Let’s say our class Lamp from above has an additional method getInternalName() which returns some internal name of the lamp for bookkeeping purposes. This property should not be exposed to the dialogue system or data access from outside. In order to allow such data hiding, you will have to declare all the databases, tables and fields that can be accessed from outside and pass these declarations to the constructor of the DialoguePackageAdapter. This is similar in principle to the way in which methods are declared (see step02). Let’s say we have two databases, obe storing lamps, and one storing media players such as TVs and radios. In our example, to allow the dialogue manager to access the three properties in class Lamp, you could do something along the lines of private static final String[] { "Lamps",”Players” }; databaseNames_ = private static final String[][] entryNames_ = { { "Name","OnOff","Brightness" }, { "Name","OnOff","Volume", "Treble", "Bass } }; private static final String[][] entryTypes_ = { { "string","boolean","int" }, { "string","boolean","int","int","int","int" } }; This declares the availability of two databases called Lamps and Players, each with one table, also called Lamps and Players. The table Lamps has the three fields OnOff, Name and Brightness of types bool, string and int. The table players has the additional fields Volume, Treble and Bass of type int. You can then construct the DialoguePackageAdapter class as follows. public Step04Package() { super(databaseNames_,entryNames_,entryTypes_,methods_,undos_); } How to make your life easier Of course, you can always use the import statement introduced in the last step to generate lexical grammar rules from databases. Again, it is transparent if the database accessed is SQL or Java or even your own database format and protocol, provided you implement the necessary stub classes. See step04.adl for the usage of the import statement.