As recommended by Yahoo on YSlow - tip #1: Make fewer HTTP request and tip #10: Minify javascript- we aim to implement these tips on all our projects with minimal head-ache. While these recommendations are truly useful, implementing them can be quite tedious and challenging. Consider having to maintain multiple min versions of the javascript and the files that links to them! So to alleviate the problem, we created a tool called low-tides (as part of open-tides) that helps automate the merging and minification of css and js files.

So what is the rationale behind the the tool?

  • Maintenance of minified js and css is a nightmare. Keeping separate js and css files for development and production can be very confusing. Some developers might change the production version without syncing with the development version. So eventually, changes to different files becomes a mess — Which one has the latest code?
  • Maintenance of html files that links to proper javascript and css is another problem. Since minified versions are likely to have different filename (e.g. basic-min.js), html codes that reference the scripts need to be changed. This leads to having multiple copies of html files… again.
  • Versioning of html, css, and js files introduce a whole new set of configuration items. Imagine bullets #1 and #2 getting multiplied across a number of version releases!
  • At the time of this writing, there are no tools available that can merge multiple javascripts. The development version of javascript needs to be logically separated while the production version needs to be merged (for lesser http request). Moreover, merging javascript is not straightforward. Some javascripts need to be pre-loaded while others can be postponed.

I suppose by now you get the picture. The solution we propose to this configuration problem is simple:  Always change from the development version and have a deployment script automatically create the production version. As such, files are always maintained from the development version - but the key to this approach is to ensure that the script for creating production versions is quick and easy-to-use.

Now here comes Low-tides. Low-tides is a Java-based program that automatically analyzes html files for javascript and css includes. It will merge includes that are in sequence into a single file and minify it. In summary, it automatically solves all the problems mentioned above.

You can download it here: http://code.google.com/p/open-tides/downloads/list

Usage instructions are available here: http://code.google.com/p/open-tides/wiki/LowTides

While it may seem that our blog activities have been quiet and slow, we have been very busy and active,  continuously expanding our operations and improving our processes. For the past three months, we have almost doubled our employee head count and we plan to add more in the next months. The only thing that hinders us right now is “space”… precious office space.

Nevertheless, we managed to prioritize things, and have decided to work on our “office space” problems first. So, this weekend we are moving to a new office space, a bigger and better office. I hope this move will help us grow as we establish our business office.

At the same time, we are working on rebranding our corporate image. Consequently, we will be launching our new website soon. Like any other thing we do, we apply continuous and iterative methodology; therefore, instead of having a grand launch and major rebranding, we will be applying our changes slowly for a span of about a month.

So watch out for this! We are changing our image in the face of the Earth!

Has anyone ever tried looking at OSWorkflow recently? It is unfortunate that this OpenSymphony project has been shelved. However, I found value in this lightweight workflow tool — for one, being lightweight makes it simple and easy to work with, plus, integration with Spring and Hibernate is readily available.

However, since OSWorkflow stopped development, there had been no support for JPA-based applications anymore. Fortunate for those interested in making JPA work on OSWorkflow via Spring, I was able to tweak some of the OSWorkflow classes and integrate it with JPA Session.

The primary problem in integrating OSWorkflow with JPA is the Session. The original session used by OSWorkflow (SpringHibernateOSWorkflowStore) is a sessionFactory injected via Spring. Since JPA uses EntityManager, the sessionFactory and EntityManager are on different transactions.

The solution is to extend AbstractHibernateWorkflowStore and use session from EntityManager. Here’s the code:

public class JPAHibernateWorkflowStore extends AbstractHibernateWorkflowStore {
    @PersistenceContext
    private EntityManager em;

	@Override
	protected Object execute(InternalCallback action) throws StoreException {
        try {
    		return action.doInHibernate((Session)em.getDelegate());
        } catch (StoreException e) {
            throw new RuntimeException(e);
        }
	}

	public void init(Map arg0) throws StoreException {
		// TODO Auto-generated method stub
	}

	/**
	 * @param em the em to set
	 */
	public void setEntityManager(EntityManager em) {
		this.em = em;
	}
}

Afterwards, use JPAHibernateWorkflowStore instead of SpringHibernateWorkflowStore as your workflow store. You will also need to copy HibernateCurrentStep.hbm.xml, HibernateHistoryStep.hbm.xml and HibernateWorkflowEntry.hbm.xml (under com.opensymphony.workflow.spi.hibernate3) to META-INF (along with persistence.xml). This will ensure that hbm mappings are recognized by the EntityManager.

Well, that’s basically it. If you are having a hard time following my instructions, try getting the standard SpringHibernateWorkflowStore to work first. Afterwards, change implementation to JPA-based approach.

Ciao!



Time for some fun! Here is a pic taken during our bowl and dine activity.

Highest scorers were Philip and Beth garnering scores of 146 and 135, respectively.

I created this basic DWR training and uploaded to Youtube. This video discuss about the basic setup of DWR and the sample is to perform an Ajax based validation.

Elegance in Approach

Another form of art in programming is the approach or architectural design. This topic requires strong technical background and experience, but still, designing your architecture requires artistic skills. There are many ways to skin a cat, so is there to design an architecture. Although design patterns help standardize approaches in software programming, decisions have to be made on which patterns to use, more so, to mix and match. Some patterns have similar purpose and overlaps, so choosing the best pattern requires some craftsmanship.

One major factor that affects architecture is the system requirements a.k.a. non-functional requirements, such as reliability, performance, maintainability and others. Having said that, I’m assuming that the functional requirements is already being taken care of and you are aware of what functionalities need to be supported… you’re now asking yourself how it should be supported.

Now, let’s go through some examples. When parsing a string for a certain pattern, do you use standard string operators (e.g. indexOf, substr) or regular expressions? Normally, you’d say regular expression will be easier - more readable and easier to maintain. However, there is a major performance degradation in regular expressions. So, if performance is important, you’d reconsider using indexOf. But then the maintaining such codes will be a nightmare. You might end up implementing your own parsing libraries using standard string operators - this will be a balanced between maintainability and performance. Such is a case of choosing the best approach, all solutions will perform the required functionality… but one will be better in some aspects than the other. Knowing which one works best requires some creativity and mastery. Thereby becoming your masterpiece.

There are so many scenarios that will let you weigh and analyze the different approaches, and there might be no perfect answer, only good answer. In any case, deriving the best possible approach requires some intuition, foresight and creativity. With so many factors to consider in choosing a design, you might as well leave it to your artistic skills to decide.

Many conceive that programming is a science of computational logic but that’s only half the truth. Programming is more than science, it’s an art. If you disagree, then you’re as good as someone fresh out of college - brainwashed on algorithms, computational complexity, and neural networks.

Let’s begin by putting things in proper context. Art, as defined in Wikipedia, is “a particular type of creative production generated by human beings” or in simpler terms “products of human creativity”. Such definition may have convinced you to agree, if not, then you’re likely a geek trying to find for the most efficient solution to the traveling salesman problem for the past 10 years.

Let’s cut the chase. So, what’s the art in programming?

Artistic Codes
There are many forms of art that can be expressed by your source code - and I’m referring to art as an aesthetic and visually stimulating piece - just like Picasso’s paintings or poems from Shakespeare.

Think of your source code as a masterpiece. Indention, comments, newlines, variable naming are your tools. All of these components must be balanced, easy to read, and inspiring.

The simplest form of art in your source code is “indention”. Block statements must be consistently indented thereby, making it easier to understand. Indention must also be equal in spaces - most Java programs are indented by 4 characters. Personally, I felt uneasy and can’t think clearly whenever I see misaligned codes. It just needs to get fixed otherwise, I won’t be able to think on the next steps.

“Comments” is another form of art but this requires a bit more creativity. Putting comments is not just rewriting what’s represented in the code, rather it must relate to a specific purpose. There is no need to describe the algorithm since its already shown in the code, instead explain the purpose of the code. Remember, comments are intended for humans to read so don’t write something in machine language. Here’s a classic example:

//loop the ArrayList
for (int i=0;i

instead try something more meaningful,

//let’s sum up all the values in the list
for (int i=0;i

The proportion of source codes to comments is also an art. If you’re writing more comments than the codes, then chances are the code is not readable and not well written. Unless of course you’re trying to write for efficiency. To illustrate:

// let’s get the middle index
mid = (max+min) >> 1;

While the code above can be easily understood using mid = (max+min)/2, you may want to use the shift operator since it takes less CPU time to shift the memory register than do a division.

The third form of art in your source code is “naming”. Choosing the right name can take a lot of thinking time. The worst variable names are generic x and y. Always use something more meaningful to make your codes more readable. More importantly, make sure the names are representative of its purpose.

For example, what variable name would you assign to “number of records per page”?

  • numberRecords. This can be interpreted a total number of records, or record number.
  • recordsPage. This can be interpreted are the page number or a list of records, or something else.
  • numRecordsPerPage. Might work, but probably too long.
  • recordsPerPage. The preferred name.

Again, it’s an art so there are no hard and fast rules how to name variable or method names. But always make sure that the names well represent it’s purpose otherwise, it can get confusing when you start debugging your source codes.

One of our project requirement is to be able to track individual users, including guests. Tracking guest/anonymous users can be quite challenging considering the different possible scenarios.

The easiest scenario is when the browser supports cookies, in such case, just assign a unique ID as a cookie and retrieve the cookie everytime access is made. The basic concept is to create an ID that will not likely be duplicated in any user. So, in our case, we used IP Address + User Agent + Forwarded For + Time + Random number. That should create unique ID for anybody accessing the site anywhere and anytime in the world.

The second scenario is when the browser doesn’t support cookies. This is more involved because we need to assign an ID unique and consistent for a specific user. In this case, we used IP Address + User Agent + Forwarded For. There are some pitfalls with this approach, such as when user changes internet connection on a DHCP network… but I guess that’s a bit of a technical limitation at the moment.

In any case, below is the code snippet used to create the unique ID key, the solution below is a combination of PHP and Javascript codes:

<?php
$IP =’none’;
//let’s try to get original IP
if ($IP = getenv(’HTTP_CLIENT_IP’)) {}
else if ($IP = getenv(’HTTP_X_FORWARDED_FOR’)) {}
else if ($IP = getenv(’HTTP_X_FORWARDED’)) {}
else if ($IP = getenv(’HTTP_FORWARDED_FOR’)) {}
else if ($IP = getenv(’HTTP_FORWARDED’)) {};
$userKey = md5($_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$IP);
if (!isset($_COOKIE["unique_id"])) {
// below is the unique user key string
$time = time();
srand($time);
// could be new user, let’s set the cookie + some more text
setcookie(”unique_id”,$userKey.$time.rand(),$time+31356000);
}
?>
<script language=”javascript”>
var userKey = ‘<?php echo $userKey; ?>’;
function getCookie(c_name)
{
if (document.cookie.length>0)
{
c_start=document.cookie.indexOf(c_name + “=”)
if (c_start!=-1)
{
c_start=c_start + c_name.length+1
c_end=document.cookie.indexOf(”;”,c_start)
if (c_end==-1) c_end=document.cookie.length
return unescape(document.cookie.substring(c_start,c_end))
}
}
return “”
}
var unique_id = getCookie(’eb_unique_id’);
if (unique_id==”") unique_id = userKey;
alert(unique_id);
</script>

We had fun at J2EE training today, JM talked about YUI, prototype, Script.aculo.us and Dojo. These javascript toolkits surely know their way around the javascript quirks that’s been perstering lots of developers with browser incompatibilities. I agree that these toolkits help a lot in making more stable javascript codes.

Some pictures taken from the training:

Some of our observations are:

  1. Lots of these toolkits do the same functionality (e.g. String utilities, Ajax calls, Animations). Is there any standard body that is defining the new sets of javascript features? So we all live in one common world of javascript coding? Or is it a battle of the best platform?
  2. Seems like we’re going back to the world of client-server days. As rich-interface becomes popular, will thin-clients begin to disappear? And what’s with Flex, Silverlight, JavaFX?
  3. When prototype popularized Object-Oriented approach, they made a good point about the power of Javascript… but still, the flexibility of javascript codes make it difficult to standardize. It’s more of a developer’s conscious effort to create cleaner code.

One neat thing I learned about prototype is that it has a method “Try.these{…}” where all the statements within will be evaluated until one actually works. Sounds useful when making your javascript methods work across multiple browser.

Today is the first day of our J2EE training. Everybody’s excited to become the first batch of the 3 months extensive training program. The training will cover open-source Java frameworks such as Spring, Struts, Hibernate, iBatis, etc. We will also cover newer technologies such as YUI, DWR. It’s going to be a tough but fun training for everyone. At the end of this training, we’ll get everyone at speed with the latest technologies on Java.

I’m happy that everyone in the team share the same passion on software development. With a little kick here and there, I’m sure we’ll get the core team in sync towards building creative software applications.

To give a preview of what’s up with Day 1, here’s a podcast on the introductory session. Unfortunatey, the audio isn’t good as I’ve placed the Macbook at the end of the room. I’ll try my Jabra tomorrow, see how that goes…

Although, the workstation didn’t arrive, the trainees were quite busy setting up the network. :)