Skip to main content

jMaki Extension for Google Gears

Posted by gmurray71 on June 11, 2007 at 4:33 PM PDT

With little effort I was able to get up and running with Google Gears very easily and integrate it with other jMaki components as an extension. Here is what I did to use the local Google database.

Using the latest jMaki .9.3 I added the following to my config.json file:

{
  'config': {
    'version': '.9',
    'glue' : {
         'includes': ['/glue.js', '/resources/system-glue.js']
       },
    'extensions': [{url : '/*', 'name' : 'google.gears'}]
    }
}

The extension is loaded for all urls and is named google.gears.
Now for the extension that will interact with Google Gears. No other JavaScript code is needed.

jmaki.namespace("jmaki.extensions.google.gears");

jmaki.extensions.google.gears.Extension = function(args) {

  var self = this;
  var topic = "/google/gears";
  var db = null;
  var factory = null;
 
  this.postLoad = function() {
     self.init();
     jmaki.subscribe(topic + "/execute", self.execute);
  }

  this.init = function() {
      jmaki.log("Google Gears jMaki Extension intialized");

      // Firefox
      if (typeof GearsFactory != 'undefined') {
          factory = new GearsFactory();
      } else {
          // IE
          try {
              factory = new ActiveXObject('Gears.Factory');
          } catch (e) {
              // Safari
              if (navigator.mimeTypes["application/x-googlegears"]) {
                  factory = document.createElement("object");
                  factory.style.display = "none";
                  factory.width = 0;
                  factory.height = 0;
                  factory.type = "application/x-googlegears";
                  document.documentElement.appendChild(factory);
              }
          }
      }
      // Now set up the objects, being careful not to overwrite anything.
      if (!window.google) {
          window.google = {};
      }
     
      if (!google.gears) {
          google.gears = {factory: factory};
      }     
  }
 
  // Open this page's local database.
  function initDB() {
      if (!window.google || !google.gears) {
          jmaki.log("Google Gears not found.");
          return;
      }
     
      try {
          db = google.gears.factory.create('beta.database', '1.0');
      } catch (ex) {
          jmaki.log('Could not create database: ' + ex.message);
      }
     
      if (db) {
          db.open('beta-database');
          db.execute('create table if not exists jmaki' +
          ' (obj varchar(2048), Timestamp int)'); 
      }
  }
 
  this.execute = function(args) {
    this.query = args.query;
    var _callback = args.callback;
    this.qargs = args.args;
    if (!db) initDB();
    if (!db) {
      jmaki.log("Google Gears Extension: Unable to find database");
      return;
    }
   var rs =  db.execute(query, qargs);
    // execture callback if it's there
    if (typeof _callback != 'undefined') _callback.call(this,rs);
  }

}

This file will need to be in a file named extension.js in the /resources/google/gears directory of your web application. Now that the extension has been enabled all you need is to publish to the topic /google/gears/execute with the data base calls you want to make from your glue code. Here is an example of mapping the save button for the Dojo Editor and Dojo Inline Edit components which publish to the topic "*onSave".

jmaki.subscribe("*onSave", function(args) {
    // empty the table then save it
    jmaki.publish("/google/gears/execute",
    { query : 'delete from jmaki',
     callback : function() {
       jmaki.log("Removing Previous Values");
       jmaki.publish("/google/gears/execute",
          { query : 'insert into jmaki values (?, ?)',
             args : [args.value, new Date()],
         callback : function() {
             jmaki.log("Saved " + args.value);
         }
        });
       }
    });
});

I used callbacks much like the XMLHttpRequest object to keep the design simple and make it easy to associate post processing code with a given event.

To display the data you need to load data from Google Gears as well. Here is the glue listener to load some text from the Google Gears data base and assign it to a JavaScript variable.

jmaki.subscribe("/jmaki/runtime/extensionsLoaded", function() {

  jmaki.publish("/google/gears/execute",
    { query : 'select * from jmaki order by Timestamp desc',
     callback : function(_rs) {
         if (typeof _rs != "undefined" &&
             typeof _rs.isValidRow != "undefined" &&
             _rs.isValidRow()) {
             // set data on the global window object for later access
             if (typeof _rs.field != "undefined") window.editorData = _rs.field(0);
             else window.editorData = "";
             jmaki.log("Loaded Editor Data: " + editorData);
         } else {
             window.editorData = "";
             jmaki.log("No data available");
         }
         jmaki.log('done');
     }
    });
});

This code is executed after the extensions has loaded and will do a database using a sql statement. The returned value is assigned to the global variable window.editorData which you can then assign to your widget. For a Editor you can assign a JavaScript variable as the value using a client side value binding which starts with an '@{' and contains the package and variable name and ends with an '}'. For this window.editorData the client side value binding is @{window.editorData}. With a JSP / JSF widget the tag in a JSP page would look like the following:

As we can see it's pretty easy to integrate Google Gears in your jMaki application. There are many other areas to explore including easier JSON serialization using gears. This is starting to like JDO all over again but in this case "J" is for JavaScript. Rest assured we will try to make this easier in jMaki.

What would you like to do with Google Gears?

Related Topics >>