A Django site.
July 23, 2010
» Weekly Update: New Features + Binary Support

Quite a varied week yet again.  The next area to cover for me is sending binary files through the module and this week has given me confidence to tackle this issue head on.

Monday – Added a datafile download utility which is accessed from the view transfers page. Only the first 40 charactors are displayed from the data and a link is added to allow downloading the data as a text file. Added a file select form element in the testSend page for allow testing of uploading whole txt files as data.

Tuesday - There was a potential security issue where controllers for http POST actions do not check for authentication before executing: Fixed these. Some preliminary investigation into how binary data can be stored as utf-8 and the appropriate mysql data type to use for this column. The module currently uses mediumtext which will be changed to longtext to accommodate larger data at the expense of 1 byte per row (which is next to nothing in the context of this module). Since the transfer mechanics are already in-place to transfer text as utf-8, the next stage of the project (into the extra credit stage now) will involve converting binary to a new number system which can be represented and transmitted in utf-8. My plan at the moment is to use the chars from UTF-8 which are stored in 1 byte, that is all the ASCII chars. These 128 chars could represent binary data as a base128 number system with 200% storage space requirement. Not ideal but the only other option is to overhaul the module to support binary transfer natively. This could be outside the scope of this summer of code project and this feature might end up not being used much anyway, so the cost to benefit ratio might not justify it. At the very least I should be able to implement the binary over utf-8 feature though to provide basic support for incorporating binary files in transfers.

Wednesday – Refactored to use Server object as property of Queue object instead of only ServerId string. This introduced many problems mainly involving unit tests. In the end I wasn’t able to get certain sql updates working without causing an error in unit tests. I ended up just scrapping one test involving a row delete since it was causing problems in dbunit regarding foreign key constraints. The dao method works completely fine however when compiled and run in the module. I am assuming it is an incompatibility in dbunit that caused this problem.

Created a queue in a test module in preparation for the demonstration so a second module being informed of data arrival can be seen in action.

Thursday – Preparation for my second openmrs dev call demonstration today. Attended the call and gave the presentation. You can view the webcast of the presentation in the post below.

Friday – Refactored to use Server object as property of Received object instead of only ServerId string. Started work on the ability to send binary files. As mentioned on Tuesday the initial plan was to encode the binary as text. After a little discussion about this on the dev call I was encouraged to look into the possibility of going straight to implementing native binary support instead of this. Today I made progress in using a BLOB to store the transfer data. This is a good starting ground to being able to transmit binary files without ever having to touch text formats.

Outcome – Got good feedback from the OpenMRS devs. I am motivated now to take the bull by the horns and go straight for native binary file support. More to come on this next week.

June 4, 2010
» JRebel, XStream, Basic Offline Transfer

Spent a lot of my second week of GSOC configuring JRebel! Still keeping to my targets though… Here is the story so far:

Weekend – Worked on serialising transfer queue objects using XStream.

Monday – Began working on the offliner transfer mechanic. Communicating with Ben and Andy about how exactly this mechanic will work in terms of the end user.  While working on the offlinetransfer java servlet I got frustrated at how long it was taking to redeploy my module everytime I wanted to try out a change, so I downloaded JRebel. This nifty little app allows hotswapping of java class files in webapps which is exactly what I need to increase my productivity.

Tuesday – Never managed to get JRebel working with OpenMRS and my module.  Been told by core devs that it might be best to wait until openmrs core directory sturcture is changed to something a little more conventional which will allow Jrebel to be set up easier.  Been persevering with the plain old redeploying method to see changes I am making.  As I am only unit testing API functions at the moment it is slightly harder to code elements such as form controllers and servlets without seeing the changes in the browser, but best not to cry over spilt milk.  It proved easy enough to get the transfer queue serialised, zipped and downloaded without Jrebel anyway:

OfflineTransferDownloadServlet.java

Wednesday – Back on the Jrebel pilgrimage again today for a bit, after more feedback from the dev list.  Got slightly further using an older version of Jrebel (v2.2) but still no luck with my module and openmrs.  Spent the rest of the day working on the receive end of the offlinetransfer mechanic.  Basically unzipping, deserialising and persisting to DB, with a few extra essentials in between.

Thursday – After some final encouragement from Jaime and Justin on the OpenMRS devlist I finally got Jrebel working.  I was getting errors because I was reffering to some jar files that had been renamed since the tutorial I was following was made. I had to rename spring-test.jar to org.springframework.test-3.0.2.RELEASE.jar to match these changes. Simple really, but easily overlooked. Thanks for the help guys. I can now modify MVC structures and view changes without having to redeploy.  Only tested it with trivial changes so far, but even that will help. Lets see how it pans out.

Attended the OpenMRS dev call today.  Many interesting presentations from fellow gsoc students.  My one will be next week.

Continuing work on offline data receive functionality.

Friday – Got receive functionality working in a basic form for offline transfer.  Still got things to clean up, like data validation etc. Also still to do is add check for if the server has received the data before.

OfflineTransferUploadServlet.java

Outcome - Keep to the targets plus I feel I have benefitted more by getting JRebel working.  It will help with faster development in the future.  I noticed though that my Servlet classes are not updating in JRebel although SPring MVC controller classes are.  Perhaps it would have been a better idea to include the functionality of these 2 servlets in controllers instead.  Nevertheless functionality is key at this stage, this could be resolved during refactoring.

May 28, 2010
» First Week of RemoteDataTransfer Module

It has all come around so fast.  Here I am after the first week of coding.  Quite a few technical setbacks this week,  but I had lots of fun, learned a lot and still think I am on schedule.  Had to get to grips with the spring framework.  I found a big difference in modifying others code that uses spring (which I had done before) and actually using spring to implement code of my own design.  Here is a breakdown of how it went.

Monday – configured barebones module and commited to repository. mainly reading today and general configuration.

Tuesday – Reading and made basic service classes and dao classes. Made record object for updating remotedatransfer_queue in the db.

Wednesday
– Implemented a method that adds a data item to a queue in the DB.  Made a webform using Spring MVC to add test items to the  queue. Tried to get debugging working in eclipse for tomcat webapps.  Ended up breaking my tomcat and openmrs installation simultaneously! Managed to fix both eventually and get debugging working in the process.  Found the tomcat plugin for eclipse helpful for launching tomcat in debugging mode as the version of tomcat i am using didn’t seem to like the standard debugging commandline
parameters.

Thursday – Bit of a problem day.  First of all when I booted OpenMRS kept going back to initialsetup and even after going through with the setup again it still wouldn’t load up openmrs.  Tried deleting everything and starting again but even this would work until I reinstalled tomcat with the latest version. Perhaps my tomcat installation got corrupted somehow.  It is all fine now but it took a sizeable chunk out the start of my day.  Read up on getting context aware unit tests working from within modules and adapted to RemoteDataTransfer.  Took a while to get all the right libraries in the classpath so I could extend BaseModuleContextSensitiveTest,  but got there eventually.  Wrote my first unit tests for the RemoteDataTransferService.  Also attended the OpenMRS dev call today.

Friday – Worked more on unit tests. Got a custom xml schema loaded into the in memory test DB for contriving test situations. These steps will insure that it is a straight forward process in the future to add more unit tests.  The ultimate goal would be test driver development for this project, or even a form of behaviour driven development.  With unit testing and debugging tomcat webapps now fully functional within eclipse this will be a more realistic aim. Created another page for the module today to view all items that are curretly stored in a queue.  I am taking these basic steps now to familiarise myself with Spring MVC further and to provide something visible within openmrs to provide a means for easy integration testing later on.  Due to this the UI elements developed so far lack conformation with OpenMRS style conventions. This will be seen to later when time is available to tweak the UI and do it properly with taglibs.  My next goals will be to work on the actual transfer mechanics of the module, which is after all the reason for it’s existence.

Outcome

I came out of these 5 days with the barebones module.  This included 2 pages for viewing and added data to a queue.  This sounds basic but the foundations of the module are now in place to begin working on the real stuff.  As mentioned much fo my time this week was spent getting to grips with and setting up the enviroment.  Hopefully next week will run smoothly because of this.  When I say next week,  I will be coding starting from tomorrow.  No rest for the wicked!

May 23, 2010
» Ready To Go

The official code start date of GSOC is tomorrow.  Things have been pretty hectic but I am looking forward to having the whole summer, starting from tomorrow, to spend coding.  I have been given write access to the OpenMRS repository and after much discussion we have finally agreed that the project name will remain the same (it was unclear for a while),  so my first steps will be to get a skeleton module uploaded.  I have also created another wiki page which contains details of my work schedule for the project.  You can see this here.  So all is green to go.  It’s going to be fun!

April 29, 2010
» OpenMRS proposal accepted for Google Summer of Code 2010!

I have been accepted by the OpenMRS community to work on the Remote Data Transfer Module as part of Google Summer of Code 2010! I am really happy about this as I will be able to spend the whole summer developing a really great piece of software that is as we speak aiding in the provision of crucial medical services in the developing world.  It is with great honour that I will work on this project and in the process improve my skills in software development. 

My next steps will be to create a project wiki page in the OpenMRS wiki, further examine the specification of the project and explore previous OpenMRS module’s code that have implemented similar features, and then compile a list of questions for my mentors from the OpenMRS community, Ben Wolfe and Andrew Kanter.  It is my target to complete these tasks and then produce a formal written set of goals to be achieved over the summer, all by the official project start date on the 24th of May.  This alongside various administrative duties and not to mention end of semester exams for uni will more than occupy the next 3-4 weeks!

Had better get on with it… More soon!

August 31, 2009
» GSoC 2008: Progress report

I have made a lot of progress on my Google Summer of Code Project.

First, I've completed the code for the generation of the directory structure for the forms. This is done using the form id, which is the name with all illegal characters removed. The only valid characters left are alpha-numeric and periods. Let me tell you, the regular expression to replace all of those characters was hell to write. But, thanks to the help of Jason Davis, I was able to make it much more readable and easier digest. You've gotta see it to get an idea of how bad it was, so here goes:


/**
* Removes all illegal characters, then removes all spaces and makes it all lower-case.
*
* @param str the form name
* @return a viable form id.
*/
public static String formNameToFormId(String str) {
return str.replaceAll("[\\$\\(\\)%`~!@#&;:\\^=\\+\\?
\"\\*\\\\////\\\\{\\}'\\]\\[\\|\\s+]", "").toLowerCase();

}

That is pretty much hell on earth to read, and it was hell on earth to type. Here's the *MUCH* simpler version:


/**
* Removes all illegal characters, then removes all spaces and makes it all lower-case.
*
* @param str the form name
* @return a viable form id.
*/
public static String formNameToFormId(String str) {
return str.replaceAll("[^a-zA-Z0-9.]", "").toLowerCase();

}

Note, you can clearly see that i'm negating that entire sequence. It does the SAME thing, but is MUCH more readable. That reads: "replace everything that isn't a letter from A to Z *OR* a to z(lower case letters) *OR* from 0 through 9 *OR* a period. Whereas the above just excluded the invalid characters explicitly but was a MONSTER of a regular expression.

Secondly, metadata persistence is written in, I'm using xstream. It's a great tool for XML serialization.

That's it. Oh, by the way, these are the things I earmarked TWO WEEKS FOR! Now, I push domain class model processing up, will work on that tomorrow.

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.

» GSoC 2008: Week 1

Okay, week 1 is nearing an end.I accomplished alot of things.

First, I completed the meta-data storage code. I wrote some tests, which revealed some bugs that needed fixing, and they were. I am happy to say, that the metadata storage works!

Writing the test was difficult due to the fact I store the forms in the system using a static List in my container class. I wound up updating to JUnit 4 to get at the @BeforeClass annotation so that the only one set of forms gets loaded into the container class. This helped me greatly. Additionally, the @AfterClass annotation was handy for cleaning up from the tests.

Secondly, Writing the code for interrogating the model was a piece of cake, thanks to groovy. All code for interrogating the model has 50 lines! That includes a model class I wrote to hold the field types and field names. I'll show you, but before I do, I should note that return statements are optional, and the final statement will be returned.


package org.openmrs.module.groovyforms.util

import java.lang.reflect.Field
import org.openmrs.module.groovyforms.metadata.model.GroovyFormsDomainModel

/*
* Utility class containing methods for class interrogation.
*/
class GroovyFormsClassUtil {
/**
* Interrogates the class for all declared fields and
* stores the type and name in a container class
* @param the {@link Class#getCanonicalName() canonical name of the class}
* @see Class#getCanonicalName()
* @return a reference to a container class containing the type
*/
static def getModel(fields) {
def domainModel = new GroovyFormsDomainModel()
def names = domainModel.fieldNames.&add;
def types = domainModel.fieldTypes.&add;
def f = fields.each {Field field ->
names field.name
types field.type.canonicalName
}
domainModel
}
}

With groovy, it's so easy and concise (as you can see). Let's explain what's going on. First, I pass in the Field array I get from Field.getDeclaredFields(). Now, groovy adds methods onto the standard JDK classes, one of those methods is a method named each() which takes a closure. Now, back to the point, I pass a Field into the closure. That closure is executed for each element (in this case, a Field). Then I add the name, and the type to a List stored in a container class, now that container class is also written in groovy!


package org.openmrs.module.groovyforms.metadata.model

/*
* Ths class holds information about the properties of the model.
*/
class GroovyFormsDomainModel {

/**
* The field names
*/
def fieldNames = []

/**
* The field types
*/
def fieldTypes = []

}

Now, the fields are Lists, not arrays. Anyways, I've gotten off on a tangent here, so let me get back on track.

What I accomplished:


Week 1:

Code to generate the directory structure, serialization of metadata back/forth between XML and POJOs (Plain Old Java Objects), Wrote tests to ensure everything works in that regard. Additionally, I wrote the code to interrogate the domain model which I will generate the forms from.

Next Week

Write up the templates for the view/controller and write code to do the generation of the view/controller. Write some tests to ensure everything generates correctly.

Unrelated to that, my stored-value card from google came today. It feels nice to be $500 richer! This is going to be the best summer, I'm already having fun doing this. It's amazing seeing the whole project evolve into something amazing.

August 3, 2009
» The overdue progress report

Apologies for not blogging as much as I should. I've focused on getting what needed to be done, done.

Tasks that have been completed thus far with a target milestone of using a mock Form, enable persistence of Questions and Values to the database:

  • Mock out a report form using the domain classes
  • Using the mocked up schema, generate a simple report form
  • Design the SQL Schema (for just FacilityDataValue and FacilityDataQuestion)
  • Write Hibernate Mapping files (for just FacilityDataValue and FacilityDataQuestion)
  • Write Data Access layer (for FacilityDataValue and FacilityDataQuestion)
  • Write Service layer (for FacilityDataValue and FacilityDataQuestion)
  • Refactor the rendering logic to use the JSP and write EL function(s) to check types using instanceof.
  • Allow a simple the mocked form from Week 1 to save the question answers.


Tasks that are are in progress, soon to be finished with a target milestone of removing the code used to mock up everything from the first few weeks; ability to use the saved schemas for rendering the report form:

  • Design SQL Schema for the rest of the domain classes
  • Write mappings for the rest of the domain classes
  • Support loading the previously saved values for a form/startdate/enddate/location into a page for viewing or editing
  • Write methods to save the rest of the domain classes in the data access layer
  • Write methods to save the rest of the domain in the service layer

Now that I have summarized work completed and in progress, let's explain the overall design:

  1. FacilityDataFormSchema serves as the overall representation of the report form in the system.
  2. FacilityDataFormSection is simply that, sections on the form, e.g., monitoring equipment status, stock status of vaccinations, number of people vaccinated, etc.
  3. FacilityDataFormQuestion holds metadata regarding a question.
  4. FacilityDataQuestion is the question itself; it specifies the datatype; it is subclassed for each question datatype; if not subclassed, then the question is considered to be "freetext" -- in other words: just simply a text-based question.
    1. CodedQuestion is a question that has a coded answer. This too is subclassed for each coded question datatype.
      1. StockQuestion is exactly as the name says, to track stock of items such as vaccinations. The coded answers are: "not_stocked_out","stocked_out","expired","not_applicable"
      2. BooleanCodedQuestion is a simple "yes","no","not applicable" type of thing; e.g., "Was there mobile clinic today?"
    2. NumericQuestion is a question which has a numeric answer, e.g., "Number of Adults Vaccinated."
  5. FacilityDataValue is what holds the values entered in the report forms for each question.
  6. FacilityDataReportFormData is a non-persisted class used for retrieving the answers for a specific report for a specified period.

Hopefully this makes up for my lack of updates.

July 14, 2009
» In the middle of GSoC: The Summer of Sync

It’s been quite a while, truth be told, quite some time without posting updates to this blog.
My GSoC project have been going through a mix being busy, many events happening, trying to find love for new things but I am sure my project is still interesting .
Today I want just to mention the status of my GSoC project ; it’s in the mid-term evaluation and we expect Google paying for all ‘well-going’ projects .

I have a detailed wiki page about my project : OpenMRS Sync, Create a new Sync Node .Everyone is welcome to leave useful comments on this project. The source code is available under the terms of OpenMRS Public Licence and can be browsed from OpenMRS website as well as they can be ‘checked-out’(downloaded) via subversion with the command

svn checkout http://svn.openmrs.org/openmrs/branches/data-synchronization-admin-ui

Other things actually are happening in my coding environment:I have been undergoing series of switching Operating Systems between Windows, Linux and Solaris and I have some insight about what does things in the best way; I have been trying to find love for Groovy/Grails at the same time I am trying the Qt toolkit .Groovy seems to be a powerfull Jav-based agile framework, easy to configure and deploy. Touching it is like drinking milk from your grandma, and when you get satisfied you feel and find that you have more energy . Qt is a cross-platform desktop GUI framework using C++and acquired by Nokia last year, Qt is the parent of KDE Desktop environment for Linux.Trying Qt is like eating bread from your granddad tagged with honey inside; you get stronger and healthier. The reality behind things like these(trying new things) should be :”Always, there is a place where you want to go, there is a person who you want to be with, there is something you always want to see happenning, there a level you always wish to be on, the is a goal you always want to achieve ! The list doesn’t end and when you feel you don’t have neither one of these desire, you don’t enjoy your life .” .

I the past 40 days, I have seen many other things happening around us and among them as I am writing: ATRACO club from Rwanda won the East-African soccer cup(CECAFA), Rwanda has named other new born gorillas (Kwitizina<www.kwitizina.org>: this is really a new brand for the Gorilla tourism in Rwanda, and it demonstrates the efforts deployed in both tourism promotion and conservation ) , Rwanda has celebrated 15 years after National Liberation and the end of Tutsis Jenocide <www.rwanda15.org>. An other event was the departurte of MJJ , the King of Pop, to the land of peace, and I can’t say anything more personal than “In paradisum deducant te Angeli; in tuo adventu suscipiant te martyres, et perducant te in civitatem sanctam Ierusalem. Chorus angelorum te suscipiat, et cum Lazaro quondam paupere æternam habeas requiem.“.

This is not the end, please stay turned to my blog and I love to hear your comments .

svn checkout http://svn.openmrs.org/openmrs/branches/data-synchronization-admin-ui