A Django site.
August 28, 2009
» GSOC 2008: Week 5

So, it's time for an update. This week got off to a sketchy start, but it's gained momentum. Let me enumerate what I have done thus far with the project. First, I've added AJAX using jquery. I figured I would use jquery mainly because it provided painless AJAX goodness. Prior to even thinking of using jquery, I wrote my own AJAX code using a tutorial that I found while googling. I had to tweak it a bit, but for the most part, it seemed very standard. However, after I wrote the AJAX equivalent code, it didn't feel too elegant. So, first I'm going to show the AJAX code I wrote; then I'll show you the jquery version; finally, I'm going to show you the servlet which handles the AJAX on the server-side.

First, the AJAX I wrote:


function AjaxValidation(url, callback) {
var req = init()
req.onreadystatechange = processRequest

function init() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest()
} else if (window.ActiveXObject) {
return new ActiveXObject("Mircosoft.XMLHTTP")
}
}

function processRequest() {
if (req.readyState == 4) {
if (req.status == 200) {
if (callback) {
chkSyntaxCallBack(req.responseXML)
}
}
}
}

this.doGet = function() {
req.open("GET", url, true)
req.send(null)
}
}
function chkSyntaxCallBack(responseXML) {
var res = responseXML.getElementsByTagName("result")[0].firstChild.nodeValue
document.getElementById("out").innerHTML = res
}

function checkSyntax() {
var target = document.getElementById("groovyModel")
var url = "${pageContext.request.contextPath}/moduleServlet/groovyforms/createGroovyForm?groovyModel=" + escape(target.value)
var ajax = new AjaxValidation(url, chkSyntaxCallBack)
ajax.doGet()
}

I warned you that it wasn't too elegant. Understanding this isn't too hard. Here is the call sequence: init() -> doGet() -> processRequest() -> chkSyntaxCallBack(). Not that bad. Now let's see the jquery version.

$(window).ready(function () {
$("#groovyModel").bind("blur", function () {
$.ajax({
type: 'POST',
data: { groovyModel: $("#groovyModel").val() } ,
url: "${pageContext.request.contextPath}/moduleServlet/groovyforms/createGroovyForm" ,
cache: false ,
success: function(data) {
var res = $(data).find("result").text()
$("#out").html(res)

}
})
});
})

Okay, that's much better. A few things are still happening here. When the window is finished loading, I bind my textarea element which has the CSS id of "groovyModel" to the blur event (lost focus). Then you see the AJAX. Now this is very straight forward. We're using the POST method, we're sending whatever value is inside of the textarea at the time the event is fired, we're posting to a servlet, not going to cache, and when we're done, it's printed to the screen. Very straight forward.

Now, like I said, this is all backed on the server-side by a servlet, which is written in Groovy. So here we go:

/**
* The contents of this file are subject to the OpenMRS Public License
* Version 1.0 (the "License") you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://license.openmrs.org
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Copyright (C) OpenMRS, LLC. All Rights Reserved.
*/
package org.openmrs.module.groovyforms.web

import javax.servlet.ServletException
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import org.apache.commons.logging.LogFactory
import org.codehaus.groovy.control.CompilationFailedException

class CreateGroovyFormServlet extends HttpServlet {
def classLoader
static final def log = LogFactory.getLog(CreateGroovyFormServlet.class)
private static final long serialVersionUID = 066373513262051L

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
def generateTemplate = request.getParameter("template")
def generateController = request.getParameter("controller")
def finalMarkup = request.getParameter("markup")
def clazz = URLDecoder.decode(request.getParameter("groovyModel"))
def name = request.getParameter("formName")
def version = request.getParameter("version")
def res = this.checkSyntax(clazz)
if (clazz) {
if (checkSyntax(clazz)) {
response.contentType = "text/xml"
response.setHeader "Cache-Conrol", "no-cache"
response.writer.write "\n\t$res\n"
} else {
response.contentType = "text/xml"
response.setHeader "Cache-Control", "no-cache"
response.writer.write "true"
}
} else {
response.contentType = "text/xml"
response.setHeader "Cache-Control", "no-cache"
response.writer.write "\n\tPlease fill in the Form Model\n"
}
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response)
}

@Override
void init() throws ServletException {
if (log.infoEnabled)
log.info("Initializing...")
classLoader = getClassLoader()
}

def getClassLoader() {
def gcl = new GroovyClassLoader(this.getClass().getClassLoader())
gcl
}

/**
* This method is used to relay errors to the user
* @param clazz the class
* @return the exception message or null if it was successful
*/
def checkSyntax(clazz) {
def sb = new StringBuilder()
sb << "import org.openmrs.*\n\n\n"
sb << clazz
def res = null
try {
getClassLoader().parseClass(sb.toString())

} catch (CompilationFailedException e) {
res = "Exception: ${e.message}"
}
res

}

/**
* Check if it is result groovy code.
* @param clazz the class
* @return whether or not it is result groovy code
*/
def isValidGroovy(clazz) {
def sb = new StringBuilder()
sb << "import org.openmrs.*\n\n\n"
sb << clazz
try {
getClassLoader().parseClass(sb.toString())
} catch (CompilationFailedException e) {
return false
}
return true
}
}


This servlet contains a lot of utility methods. One compiles, one initializes/returns the GroovyClassLoader, and of course doGet(), doPost() and init(). doGet() and doPost() both do the same thing, with doPost() simply delegating to doGet(). The code should be reasonably easy to understand. checkSyntax() returns null if it was parsed cleanly, otherwise it returns the exception message, the stack track wouldn't be useful in my case. It returns an XML tag <result> with "true" if it was successful, the exception message if it was not, and a message stating that the field must be filled in if it's empty or just not passed in. I implicitly import org.openmrs.* to allow for easier access to the OpenMRS domain model classes. The parent classloader for the GroovyClassLoader is set the servlet container's classloader. This gives me access to the classpath when loading Groovy classes.

I still have a bit to do, templating needs to be written in, for the most part it's done. Just have a few problems I'm facing, but I'll get through it. Too many people are relying on me succeeding. I feel that this project could help a lot of people, so i feel pressure to succeed. I still need to write in the "Edit" functionality of the "Manage Groovy Forms" page.

I'm definately making progress. More updates to come, that's for sure.

June 1, 2009
» DWR/AJAX/JavaScript Hacks: The secrets of JavaScript in the adress bar

A couple of weeks ago a friend of mine send me a JavaScript code that I called “Balancez-Balancez” ;  it’s really fun to play with it . Just with your browser go to any website (e.g. www.baidu.com ), then  after the page is loaded copy the following code and paste it into the address bar of your browser :
javascript:R=0;x1=0.1;y1=0.05;x2=0.25;y2=0.24;x3=1.6;y3=0.24;x4=300;y4=200;x5=300;y5=200;DI=document.links;DIL=DI.length;A=function(){for(i=0;i-DIL;i++){DI[i].style.position='absolute';DI[i].style.left=Math.sin(R*x1+i*x2+x3)*x4+x5;DI[i].style.top=Math.cos(R*y1+i*y2+y3)*y4+y5}R++;};setInterval('A()',5);void(0);

What happens: all the links in the website become a beautiful CHINESE DRAGON DANCING !

The principle of this code is collecting some HTML elements(i.e. links) and animate them continuously (changing their style positions) along an elliptical line .

It was really pretty looking and it conducted me to dig deeply and find out how to go beyond  this practice of JavaScript in the address bar for just manipulating the HTML page : I thought about AJAX .

In fact if the page has an AJAX port, meaning the back end can handle some XMLHttpRequest, you can  build an out-of-page JavaScript code that runs into the address bar of the page and calls some functions in the back-end of your application .

Example: Use DWR

Consider you have exported a DWR function that gets the app logs from the server . You can just omit to put the JavaScript imports in your page header and load them dynamically with a JavaScript in the address bar ; you can also override the Ajax Callback function, you can override the callback handler and so on . Here is the example :


javascript:
script=document.createElement('script');
script.type='text/javascript';
script.src='/js/page.js';
document.getElementsByTagName('head')[0].appendChild(script);
css=document.createElement('link');css.type='text/css';
css.rel='stylesheet';
css.href='/css/page.css';
document.getElementsByTagName('head')[0].appendChild(css);
scriptA=document.createElement('script');
scriptA.type='text/javascript';
scriptA.src='/dwr/util.js';
document.getElementsByTagName('head')[0].appendChild(scriptA);
scriptB=document.createElement('script');
scriptB.type='text/javascript';
scriptB.src='/dwr/engine.js';
document.getElementsByTagName('head')[0].appendChild(scriptB);
dwr={};
dwr.engine={};
DWREngine=dwr.engine;
DWRLogsService={};
DWRLogsService._path='/dwr';
DWRLogsService.giveMeTheLogs=function(callback){
dwr.engine._execute(DWRLogsService._path,'DWRLogsService','giveMeTheLogs',callback);
};
if(DWRLogsService==null)alert('DWRLogsService=null');
void(0);
logsHandler=function(logsList){
newTable='<table cellpadding="4" cellspacing="0" width="100%" border="0">';
for(i=0;i<logsList.length;i++){
newTable+='<tr><td>'+logsList[i]+'</td></tr>';
}
newTable+='</table>';
document.getElementById('logsDiv').InnerHtml=newTable;
};
displayLogs=function(){
DWRLogsService.giveMeTheLogs(logsHandler);
};
setInterval('displayLogs();',1000);
void(0);

Since this technique is not very fair, there are three main points you have to consider when making building the Javascript code for the address bar:

1)Avoid new line (‘\n’ or ‘\r’) or space into your code : we are in the browser address bar !

2)Don’t use the name  ‘var’ for declaring your local or global variables ; this should cause a new space into your code.

4)Call void(0) at the end of your code .

I hope this can help anyone who want to try and please leave your feedback and lets share the experience .


July 14, 2008
» You! What planet is this?

Yesterday I completed the basic functionality of the annotation system for my image viewer, using the Google Maps' marker feature. Each marker is shown as a red icon overlaid on the image. If the marker is clicked, an info window (looks like a comic book speech balloon) will open, displaying the annotation text.


So far it is possible to create new markers and view the existing ones, but they can not yet be moved, edited or deleted. This will obviously have to be implemented. Also, I would like to change the default marker icons used by the Google Maps API. Finally, the shadows that the API uses behind the markers and info windows seem unnecessary and potentially confusing, so I may remove them.

The image viewer saves and loads annotations using AJAX, so reloading the page is not necessary. The current implementation stores annotations as an XML file in the complex obs directory, but this can be changed fairly easily.


HMS Habakkuk

Though reading about my summer of code project must be quite captivating, let's move on to something even more interesting.

Project Habakkuk was a British plan to construct the world's largest aircraft carrier during WWII. This project was the brainchild of English journalist/spy/inventor/mad scientist Geoffrey Pyke, and was based on his most famous invention: Pykrete.

Pykrete is a composite material made by mixing sawdust or wood pulp with water, and then freezing it. The optimal mix is supposedly 14% sawdust and 86% ice (by weight). The properties of this material are quite impressive: It is easy and cheap to make, incredibly tough (comparable to concrete) and has a very slow melting rate.

Project Habakkuk, if successful, would have involved creating a huge, unsinkable floating island out of pykrete, probably in the Canadian winter. The top side would have been leveled to make room for one or more airstrips, and the center hollowed out for storage of 150 twin-engined bombers or fighters. Several anti-air installations would have been added, and the ship may have been reinforced with steel.

The final design called for a displacement of 2.2 million tons (the American Nimitz-class supercarriers have a displacement of 80,000-100,000 tons) and a length of more than 600 meters (twice that of the Nimitz-class, and enough for an airstrip suitable for the heavy bombers of the time). Steam turbogenerators would have supplied 26 electric motors mounted on external nacelles, similar to the way propellers are mounted on an airship.

A possible design for the HMS Habakkuk, shown next to an Iowa-class battleship and a Nimitz-class supercarrier.

HMS Habakkuk would probably have been impervious to submarine attack, and highly resistant to enemy bombing raids. Refrigeration plants would probably have been added to prevent melting, although the slow melting rate of pykrete may have enabled the ship to last for a year even without these.

Geoffrey Pyke presented his idea to British Admiral Lord Mountbatten, a favorite of Winston Churchill, and the uncle of Prince Philip. Mountbatten in turn presented the project to Churchill in 1942. Several tests were made to optimize the properties of pykrete, and a scale model was constructed in Canada.

At the Quebec Conference of 1943, Lord Mountbatten made a demonstration for a group of admirals and generals along with Winston Churchill and Franklin D. Roosevelt. Mountbatten brought a block of normal ice and a block of pykrete, to demonstrate the strength of the new material. He placed the blocks on the floor, drew his service pistol and fired at the ice block, which shattered. He then fired at the pykrete. The bullet ricocheted off the block, grazed the leg of US Admiral Ernest King, and ended up in the wall. The Admiral was highly impressed by Mountbatten's unorthodox demonstration.

Project Habakkuk began to lose priority later that year, and it quickly became apparent that the technical difficulties and the enormous resources required were too high.

It took three hot summers to completely melt the Canadan prototype.

April 22, 2008
» It's official: I'm participating in Summer of Code

Yesterday I was notified that my project application got accepted into Google Summer of  Code. I can't wait to begin! I'll be working for OpenMRS, a web based medical record system primarily focused on developing countries. During the summer I will make a medical image viewer with several features for studying and annotating images, typically X-ray photos.

My original application proposed to implement the image viewer as a Java applet. The plans have since been revised, and the plan now calls for an AJAX web app instead. I will be using the Google Web Toolkit (GWT) and  the Google Maps API during development, something I'm really looking forward to.

The change from Java applet to AJAX will lead to much better performance in low-bandwith scenarios. It will also move much of the image processing workload from the client side to the server, enabling better performance on low-end hardware but probably stressing the server somewhat more.

I will keep this blog updated with my progress during the summer, posting at least once a week.