We need to translate our model into actual code. JMatter relies on code conventions to construct a generic metamodel from our object model. Here are some of them:
- Our types must extend the base class
AbstractComplexEObject, an implementation of the
ComplexEObjectinterface, which gives our objects a number of capabilities.
- JMatter supplies a long list of what it calls Atomic Types that you must use to model basic types (that we usually use primitives for) such as strings, numbers, etc.
- We model associations using the JavaBeans-bound property conventions: that is, supply both a getter and setter method, and fire a property change event in the setter.
We model aggregation of atomic or complex types using value objects: by defining only a getter method for the member in question, and marking the backing field
We use conventions to associate icons to types: for a class named
Speaker, we supply the icon files
Speaker16.png(16x16). JMatter will use these icons in its user interface. Similarly, JMatter will automatically pick up and use a file named splash.png (or gif or jpg) as the image for the splash screen for your application.
This certainly sounds like a lot of imposition. In exchange for adhering to these conventions, JMatter promises to do a lot of the work of building a small business application for you:
- You won't have to develop a user interface for your application.
- Most persistence concerns are taken care of.
There's another issue: having to write classes by hand according to these conventions gets tedious. IDEs help us here, by providing the ability, for example, to generate getters and setters for a specified field. JMatter provides a set of IntelliJ IDEA live templates that automatically expand a few keystrokes into the necessary code: it takes the tedium out of writing the classes (also see IntelliJ IDEA support). These templates facilitate the definition of JMatter commands, fields, associations, and metadata.
An independent JMatter user, Ryan Ramage, went much further with this and developed a tool named UltraViolet, a specialization and extension of Cay Horstmann's Violet UML design tool for designing and producing JMatter applications. UltraViolet is now bundled with and integrated into the JMatter distribution. Once finished modeling, UltraViolet will generate your entire project for you, ready to run (actually, it can run it too).
A First Model Object
First, create a Java package in which to place your code. I'll be using the package name org.jmatter (feel free to use a package name suitable for your organization).
Let's start with a very simple model object. The implementation for the type
Track can be found here.
Let's do a quick analysis.
We see the base type is specified. The
@Persist annotation tells JMatter we want to persist instances to database (JMatter bundles a copy of both H2 and HSQLDB to help you get started with a minimum of fuss).
Note the usage of the atomic type
StringEO for the track's name. Note how it's modeled as a value object, with a getter method. We also use a little metadata, the
identities static field, to relate to JMatter that the name field should be unique.
Finally, we supply an implementation of the
title() method, which is a bit of text that represents an instance, somewhat similar to the
toString() method we're all familiar with.
Title is nothing more than a helper that assists with field concatenation. In fact the
title() method takes care of
toString() for you (i.e., you don't need to implement that).
This is a good time to supply an accompanying icon pair for our type. Place image resources in the directory
./resources/images. Your project's build file will automatically copy the images to the build class path. In fact, let me show you my icon selections for the types we're going to develop in this application (Figure 2). Note that I didn't supply an icon for Speaker Recognitions; we will be using custom per-instance icons for each type of recognition.
Figure 2. Application Icons
At this point, we can technically run our application and begin to get a feel for what JMatter does. Most of our model is still missing, but this is nevertheless a good time to get more familiar with JMatter. We first need to get acquainted with the ant targets in our project.
JMatter Project Ant Mechanics
The two main targets we concern ourselves with are
run. That is, from our model, we can autogenerate our database schema. The
schema-export target relies on Hibernate's schema generation capabilities, but note that JMatter autogenerates Hibernate's mapping files. When we invoke
schema-export, we're first compiling our code base, then invoking a target named
genhbm to generate the mappings, and finally sending Hibernate the instructions to export the schema to the database we specify in the file resources/hibernate.properties. This latter Hibernate configuration file defaults to using an embedded H2 database, so no configuration is required on your part.
To view the contents of the H2 database, you can launch the H2 database server with the command
java -jar h2.jar and then point your web browser to http://localhost:8082/. Also, you can verify that a mapping file was generated for the type Track by inspecting the contents of the directory build/classes/com/u2d/j1mgr, and specifically the file Track.hbm.xml.
JMatter has been in the works for some time. When this project started out, Java Persistence API (JPA) implementations did not yet exist. One area where JMatter needs to catch up is to realign its persistence implementation with the new JPA standard. JMatter today still uses autogenerated Hibernate hbm.xml mapping files. Using JPA would not only adhere to the new expected standard, but would also allow more flexibility in terms of overriding the default persistence mapping settings.
During development, and when starting out, it's simplest to run everything locally, even though the deployed application will have remote clients talking to a backend database.
Not having written a single line of GUI code and not having really given much thought to persistence, we're now ready to run our app:
Another target, named
shellscript, will produce either a
run.sh wrapper script if you need to launch the app directly from the command line.
Log in using the credentials admin/admin.
Let's begin by visually configuring the toolbar on the lefthand side, which in JMatter is termed the class bar. It's a sort of dock for types. This type of component is often called an Outlook bar (due to its debut in the Outlook application) or an Accordion (in Ajax contexts). It has two tabs. Click on the second tab, Admin and right-click Browse on the type
You should see a listing of types, including the member
Track. One way to add
Tracks to our class bar (in the
Model tab) is:
- Expand the tab in question.
- Drag and drop the
Tracktype's icon onto an empty spot inside that tab.
Alternatively, we can specify the composition of the class bar once in the configuration file located at
src/class-list.xml (an example is supplied later in this article).
Let's walk through some basics. You can right-click Browse on
Track. Since our database is brand new, there are no entries. To create a new instance, you can either right-click New on
Track or on the listing's header, which has its own context menu, or with the keystroke Ctrl-N (on a Mac, substitute the command key for control). Among other things, JMatter supports creating, editing, updating, and deleting instances. For navigation between windows, the shortcut Alt-` (Alt-backtick) is similar to the familiar Alt-tab shortcut. Also, F12 invokes a Mac Exposé-like feature that scales and spreads all your windows across the screen so they're all easily visible and selectable.
Feel free to peruse the user interface further.