Please note, new blog at http://www.acheron.org/darryl/

Use example.com for documentation and testing

Always try to use something@example.com instead of something@test.com in your testing and documentation. The domain example.com is set aside for documenation purposes. They must get enormous amounts of email "spam" at test.com (which is a real domain)... :) Try putting www.example.com into your browser, you'll get this:
You have reached this web page by typing "example.com", "example.net", or "example.org" into your web browser. These domain names are reserved for use in documentation and are not available for registration. See RFC 2606, Section 3.

ColdFusion vs. Java: Connecting to ODBC database

In my last post, I was replicating an ColdFusion array of structures in Java. This time around, I thought I would compare connecting to an Access database, executing a query, and then outputting the resultset to screen. The main thing to appreciate is how much ColdFusion does behind the scenes. You really don't have to do much, whereas in Java there is a little more to it. The tag syntax for CFML allows you to easily write complex queries, whereas this would be harder with Java. ColdFusion code <cfquery datasource="cfartgallery" name="qArtists"> SELECT * FROM artists ORDER BY lastname, firstname </cfquery> <cfoutput query="qArtists"> ID: #qArtists.artistid#<br/> Last name: #qArtists.lastname#<br/> First name: #qArtists.firstname#<br/> <br/> </cfoutput> Java code try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance(); Connection conn = DriverManager.getConnection("jdbc:odbc:artgallery"); Statement smnt = conn.createStatement(); ResultSet res = smnt.executeQuery("SELECT * FROM artists " + "ORDER BY lastname, firstname"); while(res.next()) { System.out.println("ID:" + res.getInt("artistid")); System.out.println("Last name:" + res.getString("lastname")); System.out.println("First name:" + res.getString("firstname")); System.out.println(); } conn.close(); } catch (SQLException se) { System.out.println("SQLException: " + se.getMessage()); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); }

Finally finished KOTOR2!

After 30 something hours of play (not all at once!), I've clocked Knights of the Old Republic II. It was actually pretty easy. Must play it on hard now using the Dark Side.

Adobe to acquire Macromedia - can they use tabs?

Yes, it's real! Here's the press release. Does this mean that the next version Studio will have the tabbed panels? :)

AJAX with dynamic SCRIPT tags -- revised

At work we have been experimenting with various methods of retrieving data from the server-side. The most traditional AJAX approach is by using the XMLHTTPRequest object (asynchronous or synchronous) as the transfer mechanism and XML to describe the data. Another method is using JavaScript SCRIPT tags as the transfer mechanism, and JavaScript Object Notation (JSON) or regular JavaScript syntax to "describe" the data. You can achieve this by dynamically creating JavaScript SCRIPT tags, where the source (src) is a ColdFusion template that generates JavaScript. I think that this is the easiest and quickest method of AJAX, and it really allows you to reuse your existing business logic quickly. 1. Static JavaScript file dynamically creates a SCRIPT tag via the DOM 2. The source of the SCRIPT tag is the ColdFusion template that dynamically creates the JavaScript code. As an example, let's retrieve a bunch of artists from the sample artist database that comes with ColdFusion MX. I'll then draw the artists to an existing HTML table using the DOM. By the way, this code only works in Internet Explorer (but could be easily modified to work in Firefox). Given it is an example, I have a certain license! :) display.html This is a sample HTML page that contains the empty table ready for population. Upon first load, the table is automatically populated. <html> <head> <title>JSON Test</title> <script src="artists.js"></script> </head> <body> <a href="javascript:getArtists()">Call getArtists() method -- appends to table!</a> <br/><br/> <table id="artistTable"> <caption>Artists</caption> <thead> <tr> <td>ID</td> <td>Last Name</td> <td>First Name</td> <td>City</td> </tr> </thead> </table> <script> getArtists(); </script> </body> </html> artists.js This JavaScript file contains methods that will dynamically create the SCRIPT tag. The src attribute of the SCRIPT tag is the getData.cfm ColdFusion template, which creates the JavaScript data. The populateUI method (which populates the table with the data) is only called once the SCRIPT tag's readyState has changed to "loaded". function getDataFromServer(id, url, callback) { oScript = document.getElementById(id); var head = document.getElementsByTagName("head").item(0); if (oScript) { // Destory object head.removeChild(oScript); } // Create object oScript = document.createElement("script"); var dtRf = new Date(); oScript.setAttribute("src",url + "?rf=" +dtRf.getTime()); oScript.setAttribute("id",id); head.appendChild(oScript); if (oScript.readyState!="loaded") { oScript.onreadystatechange = function() { if (this.readyState == "loaded") { eval(callback); oScript.onreadystatechange = null; } } } else { alert('Cannot load data!'); } } function getArtists() { getDataFromServer("artistData","getData.cfm","populateUI()"); } function populateUI() { oTable = document.getElementById("artistTable"); // Loop over the data in the JS array, and add to table for (var i=0; i < aData.length; i++) { // Create a new TR element oTR = oTable.insertRow(); // Create a call for each element in struct oTD = oTR.insertCell(); oTD.innerHTML = aData[i].artistid; oTD = oTR.insertCell(); oTD.innerHTML = aData[i].lastname; oTD = oTR.insertCell(); oTD.innerHTML = aData[i].firstname; oTD = oTR.insertCell(); oTD.innerHTML = aData[i].city; } } getData.cfm This ColdFusion template performs a query on the artist database. The query is then converted to an Array of Structures (using QueryToArrayOfStructures from cflib.org), and then converted to JavaScript using the CFWDDX tag. I am not *really* using JSON here. But, by using the bult-in ColdFusion JavaScript conversion functionality in the CFWDDX tag, you achieve the same result, it's just not as light-weight. <cfsetting enablecfoutputonly="true"> <cfquery datasource="cfartgallery" name="qData"> SELECT * FROM artists ORDER BY lastname, firstname </cfquery> <cfwddx action="cfml2js" input="#QueryToArrayOfStructures(qData)#" output="jscontent" toplevelvariable="aData"> <cfoutput>#jscontent#</cfoutput> There you have it! I'm pretty sure this code shall work, and I welcome any comments or improvements. It was put together pretty quickly!

ColdFusion vs. Java: Creating an Array of Structures

As I've stated before, I am starting to learn Java. After having read a few chapters on variable types (simple vs. complex), I decided to see if I can create an Array of Structures in Java. I already know that a Structure in ColdFusion is represented as a HashTable in Java, so I thought I'd start there. It didn't take long to learn that a HashMap is now considered the replacement of the HashTable object. I was also after a way of not limiting the size of the Array, given in Java you must specify a size. In ColdFusion of course you can keep adding elements to an array, as they automatically resize. The equivelent of a resizing array/collection in Java is a Vector. Upon exploring this object however, I also found that there was a newer alternative. An ArrayList also allows you to continually add elements, and it resizes automatically. Now, I had identified the object types that I wanted to use, an ArrayList of HashMaps. I could have used a Vector of HashTables, but the only real difference is they are synchronised (and that didn't seem to matter for the purposes of my tests). ColdFusion code <cfcomponent> <cffunction name="arrayOfStructures"> <cfscript> var aData = ArrayNew(1); var stItem = StructNew(); var i = 1; for (i=1; i LTE 10; i=i+1) { stItem = StructNew(); stItem.name = "Item " & i; stItem.description = "Description " & i; ArrayAppend(aData, stItem); } for (i=1; i LTE ArrayLen(aData); i=i+1) { writeoutput(aData[i].name & " : " & aData[i].description & "<br/>"); } </cfscript> </cffunction> </cfcomponent> Java code import java.util.*; public class ArrayListLoop { public static void main (String args[]) { ArrayList<HashMap> al = new ArrayList<HashMap>(); HashMap<String, String> h = new HashMap<String, String>(); Integer i; for (i=1; i <= 10; i++) { h = new HashMap<String, String>(); h.put("name", "Item" + i); h.put("description", "Description" + i); al.add(h); } Iterator it = al.iterator(); while (it.hasNext()) { // Putting (type) before "casts" it HashMap thisMap = (HashMap) it.next(); System.out.println(thisMap.get("name") + " : " + thisMap.get("description")); } // end while loop } // end main() method } // end class

Firefox article - Australian IT

Australian IT are running an article on Firefox, and how it is grabbing market share from Microsoft. I love this quote:
Firefox has to move from "evangelising to the sandals and start evangelising to the suits" to sustain growth, Ovum's Barnett says.

Google Maps and Real Estate listings

Paul Rademacher has created an example web application that overlays real estate listings over Google Maps. Very cool indeed. This of course opens up all sorts of possibilities for "store locator" style applications on the Web now.

Firefox Link Prefetching

Just saw a post on Pete Freitag's blog about Mozilla/Firefox prefetching. Apparently, you can prefetch URLs during browser idle time. From the Mozilla site:
Link prefetching is a browser mechanism, which utilizes browser idle time to download or prefetch documents that the user might visit in the near future. A web page provides a set of prefetching hints to the browser, and after the browser is finished loading the page, it begins silently prefetching specified documents and stores them in its cache. When the user visits one of the prefetched documents, it can be served up quickly out of the browser's cache.
All you have to do is place this in your code: <link rel="prefetch" href="/images/big.jpeg"> <link rel="prefetch" href="http://www.mozilla.org/projects/netlib/ Link_Prefetching_FAQ.html"> This opens up possibilities for developers to go and get content before a user has even requested it. However, it also opens up the possibilties for abuse. For instance, what if I decided to create a page that went and prefetched 10x10 MB images. Now, for someone like myself, who only has 200 MB bandwidth per month (blame Telstra!), this would be a big problem! I think they really should have limited the functionality so that you can only pre-fetch content from the same server the originating page resides. This would at least limit the exposure to such abuses. You can disable link prefetching by modifying the prefs.js file. user_pref("network.prefetch-next",false);

Time to learn other languages...

I've often been of the belief that it is good as a developer wear a few hats. I feel that I have been wearing the ColdFusion (CFML) hat for too long, to the point were it is all that I am doing. Here is my plan.
  1. Get back into Java. I've dabbled in Java a bit, having built a few CFX tags that talk to external systems. I also studied Java at University. I haven't touched it in quite some time though, and have pretty much forgotten anything useful. I think as a serious ColdFusion programmer, you've got to expose yourself to Java at some point.
  2. Extend Firefox. I'm looking forward to mucking around with the Firefox UI, and creating some of my own extensions. From what I have read, the XUL stuff is really easy to get your head around.
I'll be posting about some of my adventures in the near future!

Gmail now offering 2GB of storage

Google is now offering another gigabyte of storage for Gmail users. Google is obviously reacting from recent moves from Yahoo, who also started offering 1GB of storage. Google posted the following on the Gmail site:
Storage is an important part of email, but that doesn't mean you should have to worry about it. To celebrate our one-year birthday, we're giving everyone one more gigabyte. But why stop the party there? Our plan is to continue growing your storage beyond 2GBs by giving you more space as we are able. We know that email will only become more important in people's lives, and we want Gmail to keep up with our users and their needs. From Gmail, you can expect more.
April fools? I hope not.

OPTGROUP most unused tag?

I can't believe I've never used the OPTGROUP HTML tag before. It allows you to quickly group together items within a select list, and the groups themselves are non-selectable. <select> <optgroup label="Group 1"> <option value="1">Item 1</option> <option value="2">Item 2</option> </optgroup> <optgroup label="Group 2"> <option value="3">Item 3</option> <option value="4">Item 4</option> </optgroup> </select>