ColdFusion Searching and Sorting Algorithms

Every now and then I find a book related to programming that I put on my mental list of 'must read frequently' books - these are the books that I revisit anywhere from every 6 months to every 2-3 years, simply to stay sharp and to refresh and re-enforce the basics. In order to make this list, a book has to to be well written and be about a topic that makes me think and in some way, shape, or form teach me something every single time I read it. One day I really should post the list here for the benefit of anyone looking for a list of the best books to read to build a solid core understanding of important concepts and techniques for software design, development, and management. Today is not that day. Among this list of books is the Wrox Press "Beginning Algorithms" book (http://www.amazon.com/Beginning-Algorithms-Wrox-Guides/dp/0764596748/ref=sr_1_9?ie=UTF8&s=books&qid=1247243101&sr=1-9), which I recently re-read for the um-teenth time.

I used to (back in 2003-2005) post code on this blog very frequently - primarily APIs, implementations of design patterns, and mini-frameworks and sample applications illustrating programming techniques (AOP, OOP, etc.). It's been a while since I've encountered a subject are, technique, or concept that I felt was worth illustrating in code or hasn't already been illustrated in code by someone else... until I picked up that algorithms book for the first time in quite a while. While I read over it again I realized that nowhere that I know of has anyone provided a comprehensive overview/sample of sorting algorithms using CFML. I find that especially surprising given all of the dialogue and emphasis on taking an Object Oriented Programming approach to CF development within the devolpment community. So, I spent many of my New York City subway rides over the past month implementing sorting algorithms in CFML. The result of wihich I'm finally able to share.

I've created implementations of 6 major sorting algorithms in CFML:
  • Bubble Sort Algorithm
  • Insertion Sort Algorithm
  • Merge Sort Algorithm
  • Quick Sort Algorithm
  • Selection Sort Algorithm
  • Shell Sort Algorithm

I've also implemented the Binary Search algorithm (for searching for an object within a sorted array of objects) and the Binary Insert algorithm (for inserting an object directly into its sorted position in a sorted array of objects). In addition to implementing the sorting algorithms, I created a sample of sorting object without algorithms using Query of Queries. Each algorithm is implemented as a CFC, and should work as-is if you drop them into an application. The only code you have to write in order to implement them, is to write a comparitor function (or several if you want to be able to sort on various properties). The comparitor functions always accept 2 arguments and simply return 0 if the two items to compare are the same, 1 if the first argument is greater, or -1 if the second argument is greater. All of the algorithms accept an array of objects (technically you could also pass arrays of other data types if your comparitor functions expect them), and all of them return a sorted array. All of the algorithms support sorting in ascending and descending directions. Sorting objects that are already in memory is often times more efficient than recreating them, and these algorithms will certainly be more efficient than trying to loop/compare using some other linear 'brute force' type of approach.

I'm not going to describe the algorithms themselves here, nor am I going to get into detail about the efficiency of each compared to the others. The sample application times the sorting, inserting, and searching for you and tells you how long each took. The sample application includes an 'about' page in which I describe how each algorithm conceptually works, and I also give some suggestions about their use including recommendations about which algorithms tend to work best in certain scenarios.

You can download all of the code at http://www.horwith.com/downloads/search-sort.zip. I look forward to hearing how people put them to use as well as any other findings with them.

ColdFusion Architecture For RIAs - Part 4

This is the fourth (and last) entry in a series of blog posts I'm writing to demonstrate ColdFusion in a RIA architecture. In the first entry, I introduced the simple CF version of an address book application. In the second, we looked at how to use the built-in CF 8 features to create a version of that application that uses AJAX to improve user experience. The third installment illustrated how a Flex application could be used to leverage the existing ColdFusion application logic while delivering a user experience that is far superior to what you can easily do with HTML and JavaScript. In this last installment, I am going to show how, with a few modifications to my lovely Flex UI and a little mapping on the server, I can use my existing CF application as the model provider for LiveCycle Data Services, and take my Flex application to the next level.

We'll begin by talking about what changed on the client. For the most part, the code is the same. One change is that I'm now getting my data from a DataService tag (rather than a RemoteObject tag) - this tells Flex to talk to my LCDS data service to get data. I disabled autocommit in the DataService - if I didn't, edits to grid rows would be automatically committed on the server for me with no additional work on my part. I turned it off in order to show how you can manually handle commits. Beneath the grid are buttons to commit or rollback all of the changes you make in the grid - each button simply calls a method on the dataservice (appropriately named "commit()" and "revertChanges()"). That's right - commit/rollback functionality without writing any actual code - nice!. What's nicer is that now I can open multiple clients and browse the application, and changes made by one client immediately reflect in the grid for all other clients, and if I try to edit a grid row that another client edits at the same time, it handles that conflict for me, too - no additional client code required. Wow... thank you, DataServices! There are two other small changes in the client code. First, to initially populate the grid using a DataService, you actually tell the dataservice to "fill()" the ArrayCollection you want to populate (again - this is simpler than handling a Remote Object result event). The other change worth noting is that I added the [Managed] MetaData tag to the DTO - this tells Flex that LCDS is managing these objects on the server for me (yes, you still also leave in the [RemoteClass] directive for mapping data types, too). OK, so the client is even more robust, and was made so with less effort. Surely, this must mean I did more work on the server? Let's see.

The 4 ColdFusion Components from the first version of the application are all still intact in the LCDS version - and none of the 4 were changed in any way yet again. Again, I have added a 5th CFC, 'facade.cfc'... only my facade cfc contains a lot more code than the facade for my 'simple' Flex version. This is because in order for LCDS to expose all of that cool functionality to Flex - the ability to retrieve all of the objects, add/edit objects, handle conflicts, paginate, etc. - you must in turn expose this same functionality to LCDS from your server side application (my facade.cfc in this case). The two questions you may be asking are "What methods do you have to expose to LCDS?" and "How does LCDS know what methods to call and what to pass them?".

First, LCDS. LiveCycle Data Services works by passing requests to a user defined "destination" - remoting in CF works this way, too. A default CF installation has a "ColdFusion" destination defined in it's remoting services XML file which points at the CF Server root (so you can call any CFCs on the server) - in the case of LCDS we add a destination to our data-management-config.xml file. The LCDS destination contains a lot more information than a typical remoting destination, though. If you're using CF as the data provider, you want to specify the "coldfusion-dao" adapter for your destination (make sure you've enabled it first) and define the communication channels - for real time it's "cf-dataservice-rtmp" and for polling it's "cf-polling-amf". You then specify the component that the destination will use - in my case it's the full package name to my facade CFC. You have to specify, in a 'metadata/identity' node of the destination, the name of the property in your CFCs that is the unique identifier - this is used by LCDS for edits, conflict handling, etc. You also have a few properties you can define for the fill method (the method that gets all records) and there are other properties of the destination you can define, but for the most part, that's all you have to do. When you write Java code to talk to LCDS, in the destination you can specify the names of all the various methods to call (as well as some properties of those methods) but in the case of CF, LCDS is hard-wired to use reserve method names on the CFC you specified. So there's really very little to do to configure LCDS for CF. All the "work", as I suggested earlier, is in the component you point your destination at... so let's take a look at what I did in facade.cfc.

As I said, all of the original CFCs were left in tact - we need only expose the right functionality and data to LCDS from one CFC (facade) using reserve method names - that facade (often refered to as an Assembler) talks to my other CFCs. One thing to note is that LCDS will pass a change object (or an array of change objects) to many of these methods. That change object has methods to tell you if this is an add, edit, or delete, and has methods for getting the old data and the new data (the old and new DTOs). The methods LCDS expects and a brief description of each are as follows:
  • fill
    • Returns all entries as an array of DTOs
  • get
    • Gets one DTO - receives a structure containing the unique id of the DTO to return
  • sync
    • Sync accepts an array of change objects - for each one, the sync method passes the change object to the appropriate action method (add/edit/delete method). Those 'action' methods return the new DTO (or old if there's a conflict or some business rule failure) which is placed in an array that the sync method ultimately returns.
  • count
    • Tells LCDS how many DTOs there are.
  • create
    • Receives a change object, creates the new DTO, adds that to the newVersion property of the change object, marks the change object as 'processed', and then returns the change object
  • update
    • Receives a change object and compares it's old DTO with the matching live DTO to make sure there isn't a conflict (resulting from trying to edit a DTO that another client already edited) - if there is, it flags the conflict in the change object. If there isn't, it commits, adds the new DTO to the change object, and returns it.
  • delete
    • Receives a change object and checks to see if that DTO was already deleted (in which case it flags the change object as 'failed'). If it wasnt, the method performs the delete, adds the deleted ID to the change object to flag it as deleted to all other clients, and marks the change object as processed.

All of this might seem like a lot of work, but if you download the code (http://www.horwith.com/downloads/abook-lcds.zip) and take a look at the facade, you'll see that it's actually fairly simple to implement - especially given the functionality it allows you to drop-in to your Flex/LCDS applications. That zip file also includes the Flex LCDS code, and the config file for my LCDS server destination. If you're comfortable working with CF, using it as a provider to LCDS allows you to build very rich clients in Flex without having to struggle with client code. You could, of course, use this facade to introduce many of the same features to "regular" CF applications as well.

I hope these past 4 blog entries were useful for folks. Here are the links to the various versions of the code:
Regular CF Version
CF AJAX Version
Flex Version
LCDS Version

ColdFusion Architecture For RIAs - Part 3

This is the third of a series of four blog entries I'm writing to demonstrate CF in a RIA architecture. In the first entry, I introduced the simple CF version of an address book application. In the second, we looked at how to use the built-in CF 8 features to create a version of that application that uses AJAX to improve user experience. Although in order to create a better user experience in each version of the application I'm writing a good deal of client code, the purpose of this exercise is to examine how much refactoring/effort is needed on the server-side to support the UI changes. In this, the third installment, I am now going to replace the CF driven HTML front-end with a Flex application.

Note, I was a little lazy and kept the code and the runtime files in the default Flex Builder directory structure. As with the AJAX version, for this version of our address book application we have two objectives: re-use what we can from the first version of the code (http://www.horwith.com/downloads/abook-cf.zip) and offer some RIA benefits/characteristics by using Flex for the front end. You can download this code at http://www.horwith.com/downloads/abook-flex.zip. To test, first extract the zip file to a web root served by ColdFusion. If you haven't run the first version of the application on your server yet, you'll want to download and follow the instructions for that application in order to configure your database and datasource. You can browse the application simply by browsing the "bin-debug/main.html" file in the "abook-flex" directory created when you unzipped the compressed file, though depending on how your environment is set-up you may need to recompile the source. The interface is now extremely different (duh, it's Flex, not HTML). The A-Z links are now A-Z buttons (I could have taken a "prettier" approach but this suffices for my needs) and there's a 'show all' button. Like I said, buttons aren't the pretties way to do this in Flex (nor the fastest, in all likelihood) - I just threw them in there like that real fast. The address book entries are all displayed in a pretty data grid. I could have easily paginated it but don't mind the default scrollbar behavior for data sets this small. You can edit entries inline in the data grid, but I didn't take the time to add delete or 'add new' functionality, though it wouldn't be much effort to do so. You may notice (though in an app. this small you also may not) that the data loads a little quicker than it did with the AJAX/HTML versions. That's largely due to the fact that Flex is smart (and sneaky) about when it draws things, and partly due to the performance benefits you get out of the box by using AMF (Flash Remoting) to talk with CF. Definitely a nicer interface.

So how did the server side code need to be modified? First let's look at the old server (CF/AJAX) UI. For starters, all of the '.cfm' files are gone - replaced with a single '.mxml' file that is our application. This file has a datagrid, populated when the app initializes, for displaying all of the entries, and functions for asking the server for the entries, adding a new, empty row (add), handling edits, and for filtering the displayed entries. Basically - it's a grid populated by an ArrayCollection, with a few UI elements and some functions for passing elements of the ArrayCollection back to the server. There's also a class (a data transfer object in the 'dto' directory) that represents an address book entry - the ArrayCollection is actually an array of these. Note that the DTO class file has a [RemoteClass] metatag - this maps my server-side addressbookentry object to the AddressBookEntry AS class so my custom object types translate seamlessly back and forth. Sorting and filtering is more efficient than in the prior 2 versions of this application, as Flex has native support for filtering and sorting content on the client.

The 4 ColdFusion Components from the first version of the application are all still intact in the Flex version - and none of the 4 were changed in any way yet again. What has changed is the addition of a 5th CFC, 'facade.cfc', which is a simple implementation of the facade pattern. Like the facade in the AJAX version, this CFC accesses the user's address book the simplest way possible - by directly referencing the session scope. There are only 2 methods (and barely any code) in the component - one method for retrieving all entries and one for adding/editting an entry. Though I haven't been as diligent in trying to optimize both approaches as I possibly should be, in my opinion integrating a Flex UI with CF is much simpler and more straight forward than with an AJAX front end.

Though this Flex application really doesn't do Flex justice in terms of it's capabilities, it does do a decent job reflecting how much more robust the interface can be and how much simpler it is to integrate ColdFusion with a rich client written with Flex.

ColdFusion Architecture For RIAs - Part 2

This is the second of a series of four blog entries I'm writing to demonstrate CF in a RIA architecture. In the first entry, I introduced the simple CF version of an address book application. In this installment, we'll examine what changes need to be made to that code base in order to make it work using an AJAX client.

I'll begin by stating that, to keep with the Adobe technology theme, the AJAX functionality that ships built-in to CF 8 was chosen. These CF AJAX server enhancements were fairly well received by the CF developer community and from what I can tell were very well received by Adobe's CF clients, and I don't think anyone was surprised to see AJAX support added to the server. That said, my personal experience with the CF 8 AJAX functionality so far has left a bad taste in my mouth - at least with regards to the tags that generate an AJAX UI. As soon as you need to make them do something that isn't natively supported via the tag attributes, developers find themselves banging their head against the wall. It's that same old "trying to fit a square peg into a round hole" feeling that I run into from time to time with frameworks, CMS products, and even CFML itself on some occasions. There are a lot of excellent AJAX libraries out there and in my experience developers are often times better off downloading, learning, and using one of those... but I digress.

For this version of our address book application we have two objectives: re-use what we can from the first version of the code (http://www.horwith.com/downloads/abook-cf.zip) and offer some RIA benefits/characteristics by taking advantage of ColdFusion AJAX support. You can download this code at http://www.horwith.com/downloads/abook-ajax.zip. To test, first extract the zip file to a web root served by ColdFusion. If you haven't run the first version of the application on your server yet, you'll want to download and follow the instructions for that application in order to configure your database and datasource. You can browse the application simply by browsing the "index.cfm" file in the "abook-ajax" directory created when you unzipped the compressed file. You'll notice a few differences in the interface. The address book entries are all displayed in a pretty JavaScript grid. The entries are paginated for you, with nice navigation controls for moving around the pages... moving from page to page does not require refreshing the page in your browser. The A-Z links are still there, and work as before, but again we no longer refresh the page. The "Add Entry" button now displays a virtual window with a form, that you can submit, drag around, or close. Also, the "Edit" links have vanished - you can edit records directly inside the grid that displays them. Definitely a nicer interface.

So how did the code need to be modified? First let's look at the UI. For starters, the 'entry.cfm' file from the first version has been deleted and the form moved into a CFWINDOW in index.cfm for in-line use. Index.cfm has an ajaxproxy at the top, so we can communicate with the server from JS. The HTML table has been replaced with a CFGRID which gets it's data via the 'bind' attribute. Several JavaScript functions, all which very simple, were added to the page - primarily for refreshing the grid (via methods of the ColdFusion.Grid object) and for interacting with the add entry window (via methods of the ColdFusion.Window object). At the bottom of the page, the CF8 ajaxOnLoad() function is called to populate the grid when the page loads.

The 4 ColdFusion Components from the first version of the application are all still required for the AJAX version - and none of the 4 were changed in any way. What has changed is the addition of a 5th CFC, 'addressbookintrepretor.cfc', which is a simple implementation of the facade pattern. This CFC accesses the user's address book the simplest way possible - by directly referencing the session scope. Not a practice I generally encourage, but acceptable in a facade. There are 5 remote methods in the component - 3 of which just accept data and pass it to the address book (for deleting, adding, and editting entries). There's one entry that simply returns the current entry count (based on a filter) since the AJAX UI can no longer just reference the recordcount of whatever query is being displayed. The fifth method is the getEntries method which is used to populate (and re-populate when filtering) the data grid. This is the only method that actually has any AJAX-specific code in it - it takes the array of objects, converts it to a query, then returns the result of operating on that query with the CF 8 'queryConvertForGrid()' function.

The interface is inherentely a little prettier and the user experience is definitely more pleasant. If you've never used the CF AJAX functionality before, it takes a little while to add the code needed for this version - and if you don't know JavaScript at all it will take even longer... but for an application this simple anyone should be able to do what I did in a few hours (anywhere from 2-6 hours) with little prior experience. Were the enhancements worth the extra time? I don't really know, you tell me. What I will say is that since I'd written all the server side code and a simple HTML version already, I thought it was realistic to expect that I'd have time to add a nice interface for deleting gridrows and to write code to elegantly handle making the grid refresh and resort whenever I clicked on a header or add/edit/delete entries. Clickable headers alone is trivial, but as soon as you throw all the CRUD functionality into the mix, the amount of effort required increases to a number that, in my opinion, isn't worth it.

ColdFusion Architecture For RIAs - Part 1

This is the first of a series of four blog entries I'm writing to demonstrate CF in a RIA architecture. Each entry will take a "plain" ColdFusion application and show how it was necessary (or not) to modify the code to handle the requirements of a "Web 2.0" application. This first entry is an overview of traditional vs. next-gen web applications and is an introduction to the "plain" CF application that will be the starting point for the other three "Web 2.0" applications I describe in the next three posts.

The necessity to deploy Rich Internet (or "Web 2.0") Applications is a fact of life these days. They often deliver better ROI and competitive advantage, and today's web citizens expect and sometimes even demand a better user experience. The flash platform is, at least without a doubt in my mind, the ideal platform for delivering these applications. Some companies and developers prefer to use AJAX - and if it does what they want then that's fine for them. I'm not writing to debate the merits of one technology versus another (not today, anyway). What I want to write about is the impact that this has on the architecture of a typical ColdFusion application.

On several occasions in the past years I've written about the role of CF, in the context of next generaion web apps, changing from that of a "presentation server" that is also capable of performing business logic to that of a "service provider". For the most part this is true in the case of "Web 2.0" applications - except for those scenarios where CF is generating the RIA presentation layer (i.e. CF is creating the code for an AJAX front-end using the new CF8 CF-AJAX tags or is dynamically generating other AJAX or possibly Flex interfaces). Even then, though filling the role of presentation server, let's assume for argument's sake that CF is also filling the role of service provider. So how does all this impact the architecture of your CF application?

We'll start with a very simple address book application written entirely in CF. You can download this code at http://www.horwith.com/downloads/abook-cf.zip. To test, first extract the zip file to a web root served by ColdFusion. To set-up the application as-is, run the "create-sql-server-db.sql" file against a SQL Server 2005 database, then run "create-db-tabls.sql" against that database... create a datasource in the CF Admin named "abook" that points to the new database, then browse "populate-db.cfm" to populate your new database. All of the database related files are in the "build-db" directory created when you unzip the zip file. You can browse the application simply by browsing the "index.cfm" file in the "abook-cf" directory created when you unzipped the compressed file. There's nothing "Web 2.0" about it. There's a .cfm that shows all the entries in our address book, with links to filter by first letter of last name and links to edit records, and there's a .cfm that displays a form for adding and editting address book entries. There are also 4 ColdFusion Components, which are the "meat" of the application:
  • addressbook.cfc - represents an address book
  • addressbookentry.cfc - a data transfer object (DTO) representing an address book entry
  • addressbookdao.cfc - the parent class of all address book Data Access Objects (DAOs)
  • addressbookmssqldao.cfc - the address book DAO containing all the CRUD methods for SQL Server
Not only is there nothing "Web 2.0" about this code, but I should also state for the record that I had no intent of using it in a "Web 2.0" environment. It was actually written as part of an object orientation code exercise I conducted at Nylon Technology. This fact only makes it an ideal candidate for use in illustrating the impact of leveraging "legacy" code in next-generation applications. All of the data is cached in the session scope - the idea being that when a user logs-in, their address book(s) are loaded into the session scope and synchronization with the database actually happens behind the scenes. It's worth mentioning that to keep things simple I've taken 2 shortcuts. First, there's no actual log-in... in the real world you'd force a log-in and, at that time, select the address book IDs for all the address books owned by the current user. Second, since there's no log-in, the code is hard-wired to assume that for any request the address book ID from the database is 1. You can see this defined in the Application.cfc "onSessionStart" method.

Google Released Their Analytics API

Google released their analytics API yesterday (http://analytics.blogspot.com/2009/04/attention-developers-google-analytics.html). I haven't played with it yet, but am really looking forward to doing so very soon. A large number of our clients use analytics and it will be great to finally be able to integrate our software with it in a better, more client-friendly manner. I'm also curious to know who out there has already used the API and what you thought? Any gotchya's you want to share?

ColdFusion 8 Now FREE for Students and Educators!!!

Direct from Adobe:

"Academic institutions are experiencing increasing demand for students to develop ColdFusion skills earlier in their education to meet the high workforce demand for rich Internet application developers. Launched today to help fill this demand, Adobe makes ColdFusion 8 available for free to students and educators. Faculty can now easily integrate ColdFusion into their curriculum, enabling students to advance their Web application learning more quickly and easily and become more well-rounded developers.

Teachers and students can now use ColdFusion for free to connect to databases, Web services any other back end infrastructure to create Internet applications for learning purposes. Teachers can provide tandem instruction on the use of ColdFusion and other RIA and enterprise technologies, equipping students to graduate with comprehensive career skills in building RIAs and enterprise applications. Adobe ColdFusion 8 is now available free for download to eligible students and educators through https://freeriatools.adobe.com/coldfusion/"

Hallelujah!

Say Goodbye to MS Office

Earlier today I installed IBM Lotus Symphony and spent a little time playing with the suite today. It's really quite nice. If you haven't heard about Symphony yet, in a nutshell it is a completely free office suite developed by IBM (built on eclipse). The components are document, spreadsheet, and presentation applications (basically alternatives for Word, Excel, and PowerPoint). The application interfaces are simple and to the point, there's support for many file formats including PDF, Microsoft document, and the Open Document formats (non-proprietary) for each document type. I've been a fan of Open Office for quite some time now, but I've been a fan of IBM for longer, and Symphony appears to be a bit cleaner and nicer to use than Open Office so far.

Symphony is in beta and I haven't been using it for a really long time so I don't recommend blindly uninstalling whatever office suite you already have just yet, but I definitely recommend downloading it from http://symphony.lotus.com/software/lotus/symphony/home.jspa and giving it a shot. Hey, it's free... what do you have to lose?

CAPFUG Materials

My CAPFUG materials from the last meeting (in which I showed several ways to make CF and Flex communicate) are online at http://www.dc-flex.org/files/capfug-fds1-shorwith.zip

Cool Firefox Toolbar For Discovering New Sites

Thanks to Matt Woodward for pointing out that the StumbleUpon toolbar is also available for Firefox at https://addons.mozilla.org/en-US/firefox/addon/138. Now I can put IE back in the closet to gather more dust.

More Entries

This site is hosted by HostMySite and runs off of BlogCFC - thanks, Ray.