Hibernate Annotations for a One-To-Many Mapping Featuring a Many Side, Composite, Primary Key having a Composite, Foreign, Sub-Key

October 14th, 2008 by martykube

Sure, that’s a honking title, but it is what’s needed to describe a Hibernate mapping that recently required some head scratching on my part to figure out. I’ve been off of Hibernate (as in off of the wagon) for a while now as I’ve been busy writing stored procedures. Now that I’ve fallen back on the wagon, and am working on a Spring/Hibernate project, I’ve started to recall what a joy/pain Hibernate can be.

This project has a legacy database so I had to map the database objects as is. The relationship is between a parent and child table (or master/detail set of tables), which I’m going to refer to as Parent and Child, respectively:

Parent and Child Tables

As the title of this post indicates Parent has a composite primary key. The interesting, and tricky to handle in Hibernate item is the primary key of the child table. This is also a composite key, and a sub-key of the Child primary key is a foreign key to Parent. The DDL for this relationship gives an exact picture of the relationship:

create table parent (
  id      integer,
  version integer,
  constraint parent_pk primary key (id, version)
);

create table child (
  id      integer,
  parent_id integer,
  parent_version integer,
  constraint child_pk
    primary key (id, parent_id, parent_version),
  constraint child_fk
    foreign key (parent_id, parent_version)
    references parent (id, version)
);

Two fields from Child (parent_id and parent_version ) point back to the owning Parent (id, version). There are a couple of aspects that make this harder to model from the Hibernate perspective. All of the keys involved are composite, so you have to use embedded objects to represent each key.

Secondly, there is no separation between the link to the parent and the existence of a child instance. Hibernate is most easy to deal with when these are two different items. That is why you see recommendations 1) against unidirectional OneToMany relationships with a foreign key on the owned entity, and 2) and that you use a join table in these cases. The join table lets you separate the existence of a child (a record in the child table) from the existence of the relationship to parent (a record in the join table). In this case, since the foreign key (the link) is part of the primary key (existence), these two concept are not separated and we need to just deal with it.

Against the above recommendation, one has to go with a OneToMany with no join table. I didn’t invent how to model this, the canonical posting for relationships with composite keys are here and here. However, those posting don’t deal with the combined primary and foreign key and when both keys are composite so there is some extra detail here. I’ve packaged the example up as an Eclipse project and the complete source code is available here.

Because the keys are composite, the Java object model has embedded objects that represent the primary key values, as shown in following class diagram:

Parent and Child Class Diagram

The main domain objects are named Parent and Child, which would also hold all of the additional attributes in a real application (I’m showing only key values here for clarity). The primary key objects are ParentPrimaryKey and ChildPrimaryKey. An important point to note here is the representation of the foreign key in ChildPrimaryKey. ChildPrimaryKey holds a reference to the owning Parent as an instance variable (named parentForeignKey).

Moving on to the annotations and the coding tasks that need to be applied to each of classes, we start with Parent:

package com.beavercreekconsulting.example;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "parent")
public class Parent {

  @Id
  ParentPrimaryKey primaryKey = new ParentPrimaryKey();

  @OneToMany(mappedBy = "primaryKey.parentForeignKey",
    fetch=FetchType.EAGER)
  private List children;

  public ParentPrimaryKey getPrimaryKey() {
    return primaryKey;
  }

  public void setPrimaryKey(ParentPrimaryKey primaryKey) {
    this.primaryKey = primaryKey;
  }

  public List getChildren() {
    return children;
  }

  public void setChildren(List children) {
    this.children = children;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result
      + ((children == null) ? 0 : children.hashCode());
    result = prime * result
      + ((primaryKey == null) ? 0 : primaryKey.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    final Parent other = (Parent) obj;
    if (children == null) {
        if (other.children != null) return false;
    } else if (!children.equals(other.children)) return false;
    if (primaryKey == null) {
      if (other.primaryKey != null) return false;
    } else if (!primaryKey.equals(other.primaryKey)) return false;
    return true;
  }
}

The Entity and Table annotations are straightforward JPA annotations. The Id annotation on the primaryKey instance variable indicates that an embedded object will be used for the primary key.

The @OneToMany annotation with the mappedBy element indicates a bidirectional relationship with the Many side as the owner.

Annotation of the ParentPrimaryKey is straightforward:

package com.beavercreekconsulting.example;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
public class ParentPrimaryKey implements Serializable {

  private static final long serialVersionUID = -2912693560354598053L;

  @Column(name = "id")
  Integer id;

  @Column(name = "version")
  Integer version;

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public Integer getVersion() {
    return version;
  }

  public void setVersion(Integer version) {
    this.version = version;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((version == null) ? 0 : version.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    final ParentPrimaryKey other = (ParentPrimaryKey) obj;
    if (id == null) {
      if (other.id != null) return false;
    } else if (!id.equals(other.id)) return false;
    if (version == null) {
      if (other.version != null) return false;
    } else if (!version.equals(other.version)) return false;
    return true;
  }
}

The embeddable class needs to implement Serializable, so I added Eclipse generated serialVersionUID, hashCode() and equals().

The ChildPrimaryKey class is pretty similar to ParentPrimaryKey:

package com.beavercreekconsulting.example;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;

@Embeddable
public class ChildPrimaryKey implements Serializable {

  private static final long serialVersionUID = -452758257162645576L;

  @Column(name="id")
  Integer id;

  @ManyToOne
  Parent parentForeignKey;

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public Parent getParentForeignKey() {
    return parentForeignKey;
  }

  public void setParentForeignKey(Parent parentForeignKey) {
    this.parentForeignKey = parentForeignKey;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result
      + ((parentForeignKey == null) ? 0 : parentForeignKey.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    final ChildPrimaryKey other = (ChildPrimaryKey) obj;
    if (id == null) {
      if (other.id != null)
        return false;
    } else if (!id.equals(other.id))
      return false;
    if (parentForeignKey == null) {
      if (other.parentForeignKey != null)
        return false;
    } else if (!parentForeignKey.equals(other.parentForeignKey))
      return false;
    return true;
  }
}

The main annotations are @Column on the id field and @OneToMany on the parentForeignKey field. This class also needs to implement java.io.Serializable, so I added serialVersionUID, hashCode() and equals(). Eclipse pointed out that the hashCode() method might not work correctly due to it’s dependence on parentForeignKey unless Parent also implements hashCode(), so I added that to Parent.

The final class, Child has the most complicated annotations. The goal of the annotations is to point the persistence layer to the embedded primary key object for the purposes of object identification. Here is a quick check list of the annotation that need to be applied:

  1. The instance variable that points to the primary key object should be annotated with @EmbeddedId.
  2. Supply getters and setters for for primary key fields that are annotated with @Transient and delegate the setting and getting to the embedded primary key class.
  3. Use @AssociationOverrides to point the values of the embedded class. The name of the association to override has the form of <instance-var-name>.<embedded-class-property>.
  4. Use an @AssociationOverride for each instance variable involved. You are noting the fields of this class and how they will be mapped into the parent.
  5. For the composite foreign key, use @JoinColumn to point from the database field back to the mapped attribute in the parent object.

I do hope the above points help you to map your object in the unfortunate event that you have to deal with a similar situation. If nothing else, just copy-n-paste-n-edit from the following code:

package com.beavercreekconsulting.example;

import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name = "child")
@AssociationOverrides( {
  @AssociationOverride(name = "primaryKey.id",
    joinColumns = @JoinColumn(name = "id")),
  @AssociationOverride(name = "primaryKey.parentForeignKey",
    joinColumns = {
      @JoinColumn(name = "parent_id",
        referencedColumnName = "id"),
      @JoinColumn(name = "parent_version",
        referencedColumnName = "version") }) })
public class Child {

  @EmbeddedId
  ChildPrimaryKey primaryKey = new ChildPrimaryKey();

  public ChildPrimaryKey getPrimaryKey() {
    return primaryKey;
  }

  public void setPrimaryKey(ChildPrimaryKey primaryKey) {
    this.primaryKey = primaryKey;
  }

  @Transient
  public Integer getId() {
    return getPrimaryKey().getId();
  }

  public void setId(Integer id) {
    getPrimaryKey().setId(id);
  }

  @Transient
  public Parent getParentForeignKey() {
    return getPrimaryKey().getParentForeignKey();
  }

  public void setParentForeignKey(Parent foreignKey) {
    getPrimaryKey().setParentForeignKey(foreignKey);
  }
}

The final section of code I have is an Example class which does a set of CRUD operations with this mapping. I’ve used Spring in the example since I’m starting to believe this is Hibernate’s natural environment:

package com.beavercreekconsulting.example;

import java.util.Arrays;
import java.util.List;
import java.util.Random;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
* Main entry point for example
*/
public class Example {

  HibernateTemplate hibernateTemplate;

  public static void main(String[] args) {
    ClassPathResource resource = new ClassPathResource("beans.xml");
    BeanFactory bf = new XmlBeanFactory(resource);
    Example example = (Example) bf.getBean("example");
    example.go();
  }

  @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
  private void go() {
    create();
    read();
    update();
    delete();
    hibernateTemplate.flush();
  }

  private void update() {
    List parents = hibernateTemplate.find("from Parent");
    for (Parent p : parents) {
        Child c = new Child();
        c.setParentForeignKey(p);
        c.setId(new Random().nextInt());
        p.getChildren().add(c);
        hibernateTemplate.save(c);
    }
  }

  private void read() {
    List parents = hibernateTemplate.find("from Parent");
  }

  private void delete() {
  List parents = hibernateTemplate.find("from Parent");
  for (Parent p : parents) {
    for (Child c : p.getChildren()) {
      hibernateTemplate.delete(c);
    }
    hibernateTemplate.delete(p);
    }
  }

  void create() {
    ParentPrimaryKey ppk = new ParentPrimaryKey();
    ppk.setId(new Random().nextInt());
    ppk.setVersion(new Random().nextInt());
    Parent p = new Parent();
    p.setPrimaryKey(ppk);
    hibernateTemplate.save(p);

    Child c = new Child();
    p.setChildren(Arrays.asList(c));
    c.setParentForeignKey(p);
    c.setId(new Random().nextInt());
    hibernateTemplate.save(c);
  }

  public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
    this.hibernateTemplate = hibernateTemplate;
  }

  public HibernateTemplate getHibernateTemplate() {
    return hibernateTemplate;
  }
}

Jaxer 1.0 RC Support for REST and RPC

October 9th, 2008 by martykube

Jaxer 1.0 RC is out and getting ready to go. To me, the big news is that server side APIs such as REST and RPC protocols have been promoted to first class citizens.

Up to now, the Jaxer application server has been HTML template oriented. Jaxer is a Server Side JavaScript (SSJS) port of Mozilla, and of course, that’s a really cool thing. If you’re a JavaScript Ninja, you finally have an application server which speaks your native language.

However, up to 1.0 RC, the server side processing model has been page/template oriented. On the server side, you’ve had to provide a concrete HTML page on the server to trigger Jaxer processing. With the 1.0 RC, you can now map an URL to JavaScript files that provide the HTTP response. This feature makes is easier to provide REST or RPC interfaces on top of server side JavaScript code.

The configuration I’ve been using is Apache and the standalone Jaxer server. Jaxer comes bundled with Aptana’s Studio IDE which is the easiest configuration for getting started on Jaxer. However, you’ll have to come to terms with deploying Jaxer under Apache when you go to production (OK, sure, you can deploy to Aptana’s Cloud which deploys direct from Studio, but that’s another beta topic).

Recent releases (prior to 1.0) have allowed you to interrupt the normal template processing of page and substitute arbitrary content and content types to be returned to the client. In order to make this work, you’ve had to provide a file that Apache is configured to hand off to the Jaxer processor.

I’m working on an Jaxer application that responds to REST URLs. Here is the approach I was using for releases prior to 1.0. I wrote Apache mod_rewrite rule to hit a front controller, where the front controller is an HTML page that Jaxer processes. I added the following to my httpd.conf file:

RewriteEngine on
RewriteRule /world.* /world/index.html

My plan is that index.html will respond to REST URLs for POST, GET, PUT, and DELTE request such as :

http://<host>/world/<entity>/<id>

The one issue I ran into was that the Apache configuration that tells Apache to hand off a request to Jaxer for filtering needs a file extension and a content type. The above URL has no file extension. My solution was to place the font controller file in it’s own directory and set Jaxer filter handling to all content in the specified directory (in my httpd.conf file):

<Directory "c:/opt/xampp/htdocs/world">
JaxerFilter *
JaxerFilterContentType text/html
Order Deny,Allow
Deny from all
Allow from all
</Directory>

The good news is that the 1.0 RC allows direct specification of JavaScript files to handle REST type URLs. Tricks like the above rewrite rules won’t be need for REST. This is a big change as server side code stands alone, without a HTML page template. To me, this is the difference between a Servlet and a JSP.

With the 1.0 RC it appears that you can match URLs to execution of server side JavaScript files, which feels much more like a J2EE web.xml file which matches URLs to invocation of server side code (servlets).

I’m working up some examples of all this with 1.0 RC which aren’t quite baked yet. If you’re in a hurry to make REST work with 1.0, here are the files to look at from the standalone release:

jaxer\confs\jaxer-*.httpd.conf
jaxer\default_local_jaxer\conf\configApps.js
jaxer\framework\extensions\serviceDispatcher.js

Jaxer, E4X and Prototype

August 4th, 2008 by martykube

The ECMAScript for XML standard a.k.a “E4X” is a cool addition to JavaScript that provides for native support of XML. E4X adds nifty features such as simplified XML traversal and XML literals to the language. E4X is supported in Mozilla and Adobe JavaScript implementations. The lack of support in IE hinders the widespread adoption of E4X. However, E4x is supported on Aptana Jaxer.

I’ve been using Jaxer for web development lately. Jaxer is a web application server which uses JavaScript on the server side. The server-side JavaScript implementation is based on Mozilla, and E4X is supported. So, if you’re using Jaxer, there is nothing holding you back from using E4X on the server side.

With this in mind, I’ve cooked up an example intended to whet your appetite for E4X. The source code is shown below. The example executes a query against a database and renders each returned row as a HTML table. I’m using E4X for two tasks: storing configuration data and filling in a HTML template.

Note how various scripts or functions are tagged with runat='server'. This is how Jaxer knows which scripts to process on the server and which not to. All of the scripts in this example run on the server. The execution of the scripts is started by the onserverload attribute of the body tag. This is the server-side equivalent to the onload attribute in the browser context.

For the configuration example, I stored SQL statements in an XML document. I needed a select query to execute against the database, and then of course I realized I needed some DDL to create the table and some more SQL to insert records. I decided to store all of my queries as E4X XML literals in JavaScript embedded in my HTML page. The embedded XML is seen only on the Jaxer Server, and not in the client browser. On lines 12-37 I used an XML literal to declare an XML document containing 3 SQL statements.

A couple of points to note. First I embedded this configuration into a HTML page. With the Jaxer server-side facilities for accessing the file system, one could store the XML in a file and share the configuration across HTML pages. Second, with a CDATA section (lines 27-29), I don’t have to worry about escaping my SQL to make valid XML.

IMHO, the coolest E4X feature is simplified DOM access. The code to pull out a particular SQL statement by id is:

var sqlToRun = sqlStatements.sql.(@id == 'select-persons-no-heavier-than');

After executing the select query, I render each row as a little HTML table. On line 50 I access each record via the Jaxer.DB.ResultSet API. I create a table for each record with an XML literal on lines 52-69. One nice feature of E4X is the ability to execute arbitrary JavaScript code within the XML literal. For example, line 67:

<td>{(dbRecord.weight_kg / 0.454).toFixed(2)}</td>

reads a JavaScript object property, divides by .45, renders the number with 2 decimal places, and then places that value in the td tag. Finally on line 74, I insert the table into the page’s DOM tree. The insert is done with Prototype’s Element.insert method which takes a string or DOM Node as an argument and inserts the content into the page’s DOM tree.

Don’t forget, that all of the scripts tags (for prototype.js as well) have a runat=”server” attribute, so all of this action happens on the Jaxer server before the page is render as text and sent to the client.

One interesting point is that I used Prototype on the server side. My usage was pretty modest here; I take it as a good sign that the server side JavaScript environment closely matches the JavaScript environment in a browser.

I’m pretty happy with this example code. I think the templating of HTML turned out to be very transparent and easy to understand code. Several factors contribute to clean code: XML literals avoid cluttering the code with quoted string and also allow value interpolation, and insertion of the XML strings into the DOM tree with Prototype. This is a nice illustration of the handy features that are available in the Jaxer server side programming environment.

 <html>
     <head>
   <title>Jaxer E4X Example</title>

     /*
    * All of the JavaScript is running on the server due to the
    * runat="server" attribute of the script tags
    */
     <script runat="server" src="lib/prototype/prototype.js"></script>
     <script runat="server">

   // An XML literal holding template SQL
     var sqlStatements =
       <sql-statements>
         <sql id='create-table'>
           create table if not exists person (
             id      integer,
             first_name  varchar(20),
             last_name   varchar(20),
             birth_date  datetime,
             weight_kg   decimal(5,2),
             height_m    decimal(5,2),
             constraint person_pk primary key(id)
           );
         </sql>
         <sql id='insert-person'>
           insert into person
             (id, first_name, last_name, birth_date, weight_kg, height_m)
           values
             (?, ?, ?, ?, ?, ?)
         </sql>
         <sql id='select-persons-no-heavier-than'>
           <![CDATA[
             select * from person where weight_kg <= ?
           ]]>
         </sql>
       </sql-statements>;

     // Called on server side page load.
     // Triggered by the onserverload attribute of the body tag
       function showPersonDetails() {

     // Find a SQL statement by name
         var sqlToRun = sqlStatements.sql.(@id == 'select-persons-no-heavier-than');

     // Execute the SQL with the Jaxer.DB API
         var resultSet = Jaxer.DB.execute(sqlToRun, 200);

     // For each record returned from the DB...
     resultSet.rows.forEach(function(dbRecord, index) {
       // Create some markup using a XML Literal and value interpolation
           var tbl =
           <table border='1'>
             <tr>
               <td colspan="2">Person Detail</td>
             </tr>
             <tr>
               <td>First name:</td>
               <td>{dbRecord.first_name}</td>
             </tr>
             <tr>
               <td>First name:</td>
               <td>{dbRecord.last_name}</td>
             </tr>
             <tr>
               <td>Weight in pounds:</td>
               <td>{(dbRecord.weight_kg / 0.454).toFixed(2)}</td>
             </tr>
           </table>;

           tbl += <br/>;

       // add the new markup to the page DOM
           $('person-details').insert(tbl.toXMLString());
     });
       }

     </script>
   </head>
   <body onserverload="showPersonDetails();">
       <div id='person-details'>
       </div>
   </body>
 </html>

Jaxer CRUD

August 3rd, 2008 by martykube

Aptana’s Jaxer is a Web Application platform that uses JavaScript on the server side. I’m starting to develop a real taste for the JavaScript language, so Jaxer is a nice place to try out new modes of JavaScript programming.

Server side programming for Web Applications typically involves a good bit of interaction with a database. As a Java developer, I typically use JDBC or an Object Relational Mapping (ORM) framework such as Hibernate for database interaction. If you look around, you’ll find JavaScript lacks such established API/Frameworks for DB interaction (though it looks like some JavaScript ORMs are being actively developed). At this point in time, things are pretty much DIY.

With this in mind, I’ve worked up some code example for CRUD operations using the Jaxer database API. This is a simple example, intended to help folks climb up the Jaxer learning curve. The complete source code for the example is at the bottom of this post.

The example reads and writes from elements on a HTML page and also a database table. In the example, there are HTML tables which describe a person, and likewise, I’ve created a table in the database that has the same attributes (with slightly different names, just to keep this real. The table DDL is in the example code). Here’s a screen shot of the example:

Jaxer CRUD Example screenshoot

The flow of the example is:

1) Read attributes from the first (from the top) HTML table and then create a corresponding record in the database.

2) Read the same attributes back from the database and then populate the next HTML table

3) Read attributes from the third HTML table and update the database

4) Delete the record from the database.

Line 108 also shows an interesting capability of Jaxer: The script block there is set to runat=”server-proxy”. This tells Jaxer to run these scripts at the server, but let them be callable from the browser. So when I click the CRUD button on the client, it calls runExample on line 14, which in turn calls the four CRUD functions which run at the server. I’m actually calling a function on the server directly from the client! Note too that this example uses blocking calls from the browser to the Jaxer server. It is very easy to change this code to the Jaxer asynchronous API, which is likely topic for my next post.

Without further ado - the code:

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
   <head>
     <title>Jaxer CRUD</title>
     <script type="text/javascript" src="prototype.js"></script>

     /*
      *  Scripts that run in the client browser
      */
     <script runat='client'>
       //
       //  Run the example on button click
       //
       function runExample() {
         // server side method that creates a table if needed
         createTable();
         // Do the CRUD operations
         createPerson();
         readPerson();
         updatePerson();
         deletePerson();
       }

       // Create a person in the DB based on properties read from a HTML table
       function createPerson() {
         // pull properties from HTML table
         var p = objectFromTable('create-table');
         // write to DB via server proxy call
         createPerson_Server(p);
       }

       // Read a person from the DB and write to a HTML table
       function readPerson() {
         // read the person from the DB via a server proxy method
         var p = readPerson_Server(1);
         // populate the HTML table
         tableFromObject('read-table', p);
       }

       // Update a person in the DB based on properties read from an HTML table
       function updatePerson() {
         // read the person properties from an HTML table
         var p = objectFromTable('update-table');
         // update the DB via a server proxy call
         updatePerson_Server(p);
       }

       // Delete a person in the DB
       function deletePerson() {
         // Server call to delete in the DB
         deletePerson_Server(1);
       }

       //
       // Utility functions
       //

       // populate an object from values in a HTML table
       function objectFromTable(tableId) {
         var o = {};
         var propNames = $$('#' + tableId + ' th');
         var props = $$('#' + tableId + ' td');
         var propNum = 0;
         propNames.each(function(item) {
           o[item.innerHTML] = props[propNum++].innerHTML;
         });
         o.birthDate = dateFromStr(o.birthDate);
         return o;
       }

       // populate a HTML table from values in an object
       function tableFromObject(tableId, anObject) {
         anObject.birthDate = strFromDate(anObject.birthDate);
         var propNames = $$('#' + tableId + ' th');
         var props = $$('#' + tableId + ' td');
         var propNum = 0;
         propNames.each(function(item) {
           props[propNum++].innerHTML = anObject[item.innerHTML];
         });
       }

       // convert from string 'yyyy-mm-dd' to JS Date
       function dateFromStr(dateStr) {
         if(dateStr) {
           var dateParts = dateStr.split('-');
           var date = new Date();
           date.setFullYear(dateParts[0]);
           date.setMonth(dateParts[1] - 1);
           date.setDate(dateParts[2]);
         }
         return date;
       }

       // convert from JS Date to string 'yyyy-mm-dd'
       function strFromDate(aDate) {
         var str = '';
         if(aDate) {
           str +=  (aDate.getFullYear() +  (aDate.getMonth() + 1) + aDate.getDate());
         }
         return str;
       }
     </script>

     /*
      *  Scripts that run on the server.
      *  Jaxer generated stubs are used to call these from the client.
      */
     <script runat='server-proxy'>

       //
       // Server side persistence functions
       //

       // Write a new object to the DB
       function createPerson_Server(person) {
         // execute insert statement, binding to properties of passed in person
         Jaxer.DB.execute(
           'insert into person ( '+
             '  id, first_name, last_name, birth_date, weight_kg, height_m ' +
           ' ) values (?, ?, ?, ?, ?, ?);',
           person.id, person.firstName,
           person.lastName, person.birthDate,
           person.weightInKilograms, person.heightInMeters
         );
       }

       // Read an existing record and return a JavaScript object
       function readPerson_Server(id) {
         // execute query and receive returned a Jaxer.DB.ResultSet
         var resultSet = Jaxer.DB.execute('select * from person where id = ?;', id);
         // select the first row since weonly care about 1 person
         var aRow = resultSet.rows[0];
         // map DB column names to front end column names
         var person = {
           id: aRow.id,
           firstName: aRow.first_name,
           lastName: aRow.last_name,
           birthDate: aRow.birth_date,
           weightInKilograms: aRow.weight_kg,
           heightInMeters: aRow.height_m
         };
         // return to client for display
         return person;
       }

       // From a JS Object, update a row in the DB
       function updatePerson_Server(person) {
         // Update all fields for the given primary key value
         Jaxer.DB.execute(
           'update person set  '+
             '  first_name = ?, last_name = ?, birth_date = ?, weight_kg = ?, height_m = ? ' +
           ' where id = ?;',
           person.firstName, person.lastName, person.birthDate,
           person.weightInKilograms, person.heightInMeters,
           person.id
         );
       }

       // Delete a record in the DB
       function deletePerson_Server(id) {
         Jaxer.DB.execute('delete from person where id = ?;', id);
       }

       //  Create a table if the table is not already in the DB
       function createTable(){
         Jaxer.DB.execute(
           'create table if not exists person (   ' +
           ' id      integer,   ' +
           ' first_name  varchar(20),   ' +
           ' last_name   varchar(20),   ' +
           ' birth_date  datetime,   ' +
           ' weight_kg   decimal(5,2),   ' +
           ' height_m    decimal(5,2),   ' +
           ' constraint person_pk primary key(id)); '
         );
       }
     </script>
     <style>
       .big-cap {
         color: blue;
         font-size:larger;
         font-style:italic;
       }
       body {
         font-family:Arial;
         font-size: 10pt;
       }
     </style>
   </head>
   <body>
     <h3><span class="big-cap">C</span>reate a person from this table</h3>
     <table border="1" style="text-align: center" id="create-table">
       <tr>
         <th>id</th>
         <th>firstName</th>
         <th>lastName</th>
         <th>birthDate</th>
         <th>weightInKilograms</th>
         <th>heightInMeters</th>
       </tr>
       <tr>
         <td>1</td>
         <td>John</td>
         <td>Doe</td>
         <td>1975-11-20</td>
         <td>90.7</td>
         <td>1.82</td>
       </tr>
     </table>
     <hr/>
     <h3><span class="big-cap">R</span>ead a person and populate this table</h3>
     <table border="1" style="text-align: center" id="read-table">
       <tr>
         <th>id</th>
         <th>firstName</th>
         <th>lastName</th>
         <th>birthDate</th>
         <th>weightInKilograms</th>
         <th>heightInMeters</th>
       </tr>
       <tr>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
         <td></td>
       </tr>
     </table>
     <hr/>
     <h3><span class="big-cap">U</span>pdate a person from this table</h3>
     <table border="1" style="text-align: center" id="update-table">
       <tr>
         <th>id</th>
         <th>firstName</th>
         <th>lastName</th>
         <th>birthDate</th>
         <th>weightInKilograms</th>
         <th>heightInMeters</th>
       </tr>
       <tr>
         <td>1</td>
         <td>Jane</td>
         <td>Smith</td>
         <td>1978-1-1</td>
         <td>89.2</td>
         <td>1.76</td>
       </tr>
     </table>
     <hr/>
     <h3><span class="big-cap">D</span>elete person with id = 1</h3>
     <hr/>
     <button onclick="runExample();">Crud</button>
   </body>
 </html>

Using html2wiki for Google Code

May 14th, 2008 by martykube

I recently released a HTML to Google Code wiki converter.  Now that the module is published on CPAN, it’s time to provide some usage instructions.

If you’re an experienced Perl hacker, see

perldoc HTML::WikiConverter

and

perldoc HTML::WikiConverter::GoogleCode.

If you’re not a Perl hacker, read on…

There are two ways to use the module; the easiest is via a shell script, html2wiki:

http://search.cpan.org/~diberri/HTML-WikiConverter/bin/html2wiki.

which is provided as part of the HTML::WikiConverter Perl module. The other option is to write your own Perl script and include the Google Code module. Using html2wiki is easier as you only have to supply the desired command line options. Writing your own script is the more flexible and powerful option. I’m going to cover the html2wiki option in detail, and then briefly cover an example Perl script.

Installation

Before you can use the converter, you’ll need to have Perl installed. I use ActiveState’s binary distribution for Windows; The installation instructions are here:

http://aspn.activestate.com/ASPN/docs/ActivePerl/5.10/install.html.

The you’ll need to install Perl modules HTML::WikiConverter and HTML::WikiConverter::GoogleCode. There are a couple of ways to install these modules; you can download the tar files from cpan.org, or use ppm if you have the ActiveState Perl distribution. My favorite method is to use the Perl CPAN module which is part of the core Perl distribution. The following shell commands should get you close:

>perl -MCPAN -e shell
cpan> install HTML::WikiConverter
CPAN: Storable loaded ok (v2.16)
...
cpan> install HTML::WikiConverter::GoogleCode
CPAN: Storable loaded ok (v2.16)
...
cpan>

Line 1 invokes the CPAN module in an interactive mode. If you have any trouble, just type help at the cpan> prompt.

At this point, html2wiki should be installed. From a command prompt, you should be able to summon up the usage instructions:

>html2wiki
Usage:
    html2wiki [options] [file]
    Commonly used options:
        --dialect=dialect    Dialect name, e.g. "MediaWiki"
...

You should also be able to verify that the Google Code dialect is installed.

>html2wiki --list
Installed dialects:
GoogleCode
...

Using html2wiki

For this example, I put some random HTML in file named example.html:

>type example.html
CamelCase words like JavaScript, <pre>JavaScript</pre> and
<b>bold</b> words,and html tokens: 1 < 1

Using the Windows cmd.exe shell, the default conversion to wiki markup looks like this:

>html2wiki --dialect=GoogleCode < example.html
CamelCase words like JavaScript,

{{{
JavaScript
}}}

and *bold* words, and html tokens: 1 &amp;amp;amp;lt; 1

The default conversion escapes HTML tokens such as < by replacing them with the HMTL escape sequence (&lt;, in this case). The Google Code wiki will render &lt; as &lt; not what we want (<). To turn escaping off, set the -–no-escape-entities option:

html2wiki --dialect=GoogleCode ^
     --no-escape-entities ^
     < example.html

The output is now:

CamelCase words like JavaScript,

{{{
JavaScript
}}}

 and *bold* words, and html tokens: 1 < 1

The next adjustment I make is to turn off the Google Code feature of automatically turning CamelCase words into wiki links. The documents I’ve been posting turn out to have many CamelCase words for most of which I do not want the automatic link. The wiki markup to disable link generation is to proceed the word by an exclamation mark. I’ve added an option to enable this feature for specific words. For example, to prevent link generation for the words CamelCase and JavaScript, modify the html2wiki command to be:

html2wiki --dialect=GoogleCode ^
     --no-escape-entities ^
     --escape-autolink=CamelCase ^
     --escape-autolink=JavaScript ^
     < example.html

The generated wiki markup from this command is:

!CamelCase words like !JavaScript,

{{{
JavaScript
}}}

and *bold* words, and html tokens: 1 < 1

In this case, the CamelCase words are escaped, except when the word occurs in within a <pre> tag (line 4).

The last Google Code feature of note is the ability to embed page summary and labels within the wiki markup. The page summary is a comment on the first line which is displayed on the project’s wiki index. Likewise, the labels markup element is a comment and is used by Google Code. For example, when the label ‘Featured’ is applied to a wiki page, a link to the page is created on the project’s front web page. The final example shows adding a summary and two labels to the wiki markup. The html2wiki command is:

html2wiki --dialect=GoogleCode ^
     --no-escape-entities ^
     --escape-autolink=CamelCase ^
     --escape-autolink=JavaScript ^
     --summary="This is a great page" ^
     --labels=Featured ^
     --labels=Phase-Deploy ^
     < example.html

and the generated wiki markup is:

#summary This is a great page
#labels Featured,Phase-Deploy
!CamelCase words like !JavaScript,

{{{
JavaScript
}}}

and *bold* words, and html tokens: 1 < 1

Using H::WC::GoogleCode in a Perl Script

This last example shows a Perl script that makes use of the options show above. This example is a script I’ve used to convert a Developer’s Guide saved as HTML into wiki markup. The source code for the script follows below.

On line 5, the H::WC module is imported. I didn’t import the H:::WC::GoogleCode module since it is imported by H::WC based on the dialect name.

This document has a long list of CamelCase words for which I wanted to suppress generation of links. These words are collected into an array on line 7. Line 22 sets up a hash with keys of the path to the HTML document and values of the path where the generated wiki markup should be stored.

On line 26, and new instance of H::WC is created. Line 27 pulls in the H::WC::GoogleCode module. Line 28 passes the list of CamelCase words. Line 29 turns off escaping of HTML entities.

For images, the HTML document uses relative links to images stored on the file system (at ../docs/img). In order to support the wiki, I’ve staged the images on my web server under /img and passed in the web-site URI on line 30. The relative image links are turned into absolute URLs pointing to my web server in the wiki markup.

The final option, the summary parameter on line 30, generates a page summary on the wiki.

The balance of the script pulls in the HTML, converts it with the H::WC instance (line 42), and writes the wiki markup to a file.

 #!/usr/bin/perl -w

 package main;
 use strict;
 use HTML::WikiConverter;

 my @toEscape = qw/
              SqlMapClient
              JBati
              SqlMapClientBuilder
              JavaScript
              NovaJug
              ExampleJSS
              SqlLite
              ExamplesJSS
              SqlMap
              MySql
              SqlMapConfig
              DevGuide
 /;

 my %to_process = qw /
      ..\docs\DevelopersGuide.html</pre>
 /;

 my $wc = new HTML::WikiConverter(
      dialect => 'GoogleCode',
      escape_autolink => \@toEscape,
      escape_entities => 0,
      base_uri => 'http://beavercreekconsulting.com',
      summary => 'Developers Guide V0.2 - jBati usage and examples'
 );

 foreach my $in (keys %to_process) {

      open(HTML, "<$in") or die "cannot open $in: $!\n";
      my $html = do {local $/; <HTML>};
      close(HTML);

      open(WIKI, '>' . $to_process{$in}) or die "cannot open " .
              $to_process{$in} . ": $!\n";
      my $converted = $wc->html2wiki($html);
      print WIKI $converted, "\n";
      close(WIKI);
 }

HTML to Google Code wiki Converter

May 13th, 2008 by martykube

I’ve written a HTML::WikiConverter dialect for Google Code. The module, HTML::WikiConverter::GoogleCode, is now available on CPAN at http://search.cpan.org/~martykube/.

I wrote the module to support an open source project I’m working on. The module allows me to write my documentation in a good editor (OpenOffice in this case), save the document as HTML, convert it to Google Code wiki markup, and then post the file to my project wiki via svn. The main advantage is that I can also include the HTML documentation in the release file and thereby have one version of a document that is posted on the wiki and included as part of a release.

That’s the short story, read on for the long story…

I recently started an open source project (shameless plug… the project is jBati, a JavaScript ORM library) hosted at Google Code. One nice feature of Google’s project hosting is that each project has wiki. The project’s wiki is a nice place to post information as potential consumers can see the project documentation without having to download a release.

However, there are a couple of drawbacks to the wiki. The wiki editor is a plain HTML text box. This is serviceable enough for short documents but doesn’t work well for larger documents. Also, for someone like me who depends heavily on a spell checker, unless my browser does the checking, there is no spell checking.

The other drawback is that some documents, such as a User’s Guide, need to be posted on the wiki and also distributed with releases. There seemed to be one of two ways to accomplish this, either convert from the wiki to documents for release (which need to be in a text or HTML format), or, convert from the release documents to the wiki format.

I figured I wasn’t the first one with this idea and looked around. I found a wiki to HTML tool, an on-line wiki to HTML converter (http://jtidy.de/), and a really hard to read blog which reported that the Perl module HTML::WikiConverter did a decent job of converting HTML to Google Code wiki syntax.

I’m a Perl guy, so the HTML::WikiConverter module sounded like a winner. The HTML::WikiConverter comes with a set of plug-ins to support various wiki dialects. The recommend wiki dialect that gets closest to the Google Code wiki dialect is MoinMoin. The results were decent, yet some hand editing was needed to get perfect results. IMHO, once you choose a generation route like this (HTML wiki), the tool chain has to work without intervention, otherwise you loose much of the advantage due to things getting out of sync.

So, I decided to fix this one for good and wrote a Google Code wiki dialect. I’m currently writing my project documentation with OpenOffice and saving the files as HTML. I use HTML::WikiConverter to generate wiki markup and then post the wiki files to the Google Code via svn.